xcode 允许用户通过点击选择 UIPickerView 行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2403262/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 19:10:31  来源:igfitidea点击:

Allowing user to select a UIPickerView row by tapping

iphoneobjective-cxcodeuipickerview

提问by camilo

I'm trying to use a UIPicker View with a behavior somehow different of what's usually seen in iPhone code examples.

我正在尝试使用 UIPicker 视图,其行为与 iPhone 代码示例中通常看到的行为有些不同。

What I want to do is to allow users to scroll through the picker contents, but not to select a picker's row automatically (using the "didSelectRow" method from picker's delegate). Instead, I want to allow the user to touch the center row of the picker, which gets highlighted, and becomes the selection.

我想要做的是允许用户滚动选择器内容,而不是自动选择选择器的行(使用来自选择器委托的“didSelectRow”方法)。相反,我希望允许用户触摸选择器的中心行,该行被突出显示并成为选择。

Is there any way to achieve this?

有没有办法实现这一目标?

Thanks in advance.

提前致谢。

回答by Martin Linklater

Add a gesture recogniser to the UIPickerView which triggers a target method in your object:

向 UIPickerView 添加手势识别器,它会触发对象中的目标方法:

myGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pickerTapped:)];
[myPicker addGestureRecognizer:myGR];

// target method

-(void)pickerTapped:(id)sender
{
// your code
}

回答by Joey

  1. make a new UIControl

    • same position as the UIPickerView
    • [yourcontrol setBackGroundColor: [UIColor clearColor]];
  2. make a method

  1. 创建一个新的 UIControl

    • 与 UIPickerView 相同的位置
    • [yourcontrol setBackGroundColor: [UIColor clearColor]];
  2. 制定一个方法

- (IBAction) pickerControlTapped 
{
    [yourpicker selectRow: rand()% yourpickersize
              inComponent: 0
                 animated: YES];
}

.3. make a connection between 1 and 2

.3. 在 1 和 2 之间建立联系

 
[yourcontrol addTarget: self 
                action: @selector(pickerControlTapped) 
      forControlEvents: UIControlEventTouchUpInsied];

回答by richy

Building on Martin Linklater's answer to support tapping on the pickers other rows: Has some magic numbers but works for me.

以 Martin Linklater 的回答为基础,支持点击其他行的选择器:有一些神奇的数字,但对我有用。

- (void) pickerTapped:(UITapGestureRecognizer*)gestureRecognizer
{
    CGPoint location = [gestureRecognizer locationInView:self.pickerView];

    CGFloat halfViewHeight = self.pickerView.frame.size.height / 2;

    NSInteger row = -1;
    if (location.y < halfViewHeight - 22
        && location.y > halfViewHeight - 66)
    {
        row = [self.pickerView selectedRowInComponent:0] - 1;
    }
    else if (location.y < halfViewHeight + 22
             && location.y > halfViewHeight - 22)
    {
        row = [self.pickerView selectedRowInComponent:0];
    }
    else if (location.y < halfViewHeight + 66
             && location.y > halfViewHeight + 22)
    {
        row = [self.pickerView selectedRowInComponent:0] + 1;
    }

    if (row >= 0 && row < [self.content count])
    {
        id element = [self.content objectAtIndex:row];

        if (element)
        {
            [self.pickerView selectRow:row inComponent:0 animated:YES];

            // do more stuff
        }
    }
}

回答by SHaKie

I have a relatively simple solution to this problem that has worked well for me. Using a hidden custom button you can achieve the tap functionality without a gesture recogniser. This solution works for a picker with one component, however I'm sure it could be adapted to work with more.

对于这个问题,我有一个相对简单的解决方案,对我来说效果很好。使用隐藏的自定义按钮,您可以在没有手势识别器的情况下实现点击功能。此解决方案适用于具有一个组件的选择器,但我相信它可以适用于更多组件。

Firstly add a button, either in the Interface Builder or programatically. Make it hidden and as wide as the picker then place it so that it sits exactly in the centre of the picker and also in front of it in the view hierarchy.

首先在界面生成器中或以编程方式添加一个按钮。将其隐藏并与选择器一样宽,然后将其放置在选择器的中心,并在视图层次结构中位于它的前面。

I'm using an IBAction like this to show my picker. However it's really up to you how you show and hide the picker.

我正在使用这样的 IBAction 来显示我的选择器。但是,如何显示和隐藏选择器完全取决于您。

- (IBAction)showPicker:(id)sender
{
    _picker.hidden = NO;
    _buttonPicker.hidden = NO;
}

All the action for choosing the picker value happens in an IBAction for the UIControlEventTouchUpInside event, something like this.

选择选择器值的所有操作都发生在 UIControlEventTouchUpInside 事件的 IBAction 中,类似这样。

- (IBAction)selectPicker:(id)sender
{
    //Hide the button so that it doesn't get in the way
    _buttonPicker.hidden = YES;

    //Make sure we're within range
    NSInteger max = _values.count;
    NSInteger row = [_picker selectedRowInComponent:0];
    if(row >= 0 && row < max) {
        NSString *value = [_values objectAtIndex:row];

        //Set the label value and hide the picker
        _label.text = value;
        _picker.hidden = YES;
    }
}

I've slightly modified the code for this answer from working code so apologies if it's broken at all.

我已经从工作代码中稍微修改了这个答案的代码,所以如果它被破坏了,我深表歉意。

回答by Joey

There are only 2 delegates for UIPickerView.

UIPickerView 只有 2 个代表。

So, we can use only 7 methods to control UIPickerView by delegate.

因此,我们只能使用 7 种方法来通过委托来控制 UIPickerView。

– pickerView:rowHeightForComponent:
– pickerView:widthForComponent:
– pickerView:titleForRow:forComponent:
– pickerView:viewForRow:forComponent:reusingView:
– pickerView:didSelectRow:inComponent:
– numberOfComponentsInPickerView:
– pickerView:numberOfRowsInComponent:

– pickerView:rowHeightForComponent:
– pickerView:widthForComponent:
– pickerView: titleForRow:forComponent: – pickerView:viewForRow:
forComponent:reusingView:
– pickerView:didSelectRow:inComponent:
– numberOfComponentsInPickerView:
– pickerView:numberOfRowsInComponent:

that'all.

就是这样。

In UITableViewDelegate case, there are more methods for UITableView for managing selections. such as, – tableView:willSelectRowAtIndexPath:
– tableView:didSelectRowAtIndexPath:
– tableView:willDeselectRowAtIndexPath:
– tableView:didDeselectRowAtIndexPath:

UITableViewDelegate 案例中UITableView有更多的方法来管理选择。例如, – tableView:willSelectRowAtIndexPath:
– tableView:didSelectRowAtIndexPath:
– tableView:willDeselectRowAtIndexPath:
– tableView:didDeselectRowAtIndexPath:

However...

然而...

In UIPickerViewDelegate case, there is only 1 method for responding to row selection.

在 UIPickerViewDelegate 情况下,只有 1 种方法可以响应行选择。

– pickerView:didSelectRow:inComponent:

– pickerView:didSelectRow:inComponent: