【问题标题】:Allowing user to select a UIPickerView row by tapping允许用户通过点击来选择 UIPickerView 行
【发布时间】:2010-03-08 17:28:49
【问题描述】:

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

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

有什么办法可以做到吗?

提前致谢。

【问题讨论】:

  • 您能更好地解释一下为什么 didSelectRow 方法在这里对您没有帮助吗?您是否尝试过使用它,如果是,您遇到了什么问题?
  • 问题在于它的工作方式与预期相同。 :-/ 基本上我似乎是一个pickerView,其中选择器会自动选择其中一个行值,但它只在用户触摸它时选择一个值。我试图做同样的事情,但我做不到。

标签: iphone objective-c xcode uipickerview


【解决方案1】:

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

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

// target method

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

【讨论】:

  • Martin,我偶然发现了您的解决方案,发现它很有帮助。如此简单,它的工作原理。唯一的问题是,在我对点击的响应中,如何将点击传递给选择器,以便我在被点击的行处获得对象,而不是在中心的对象?
  • @DeanDavids 您指向的页面似乎不再存在。你能提供另一个,或者解释一下解决方案吗?
  • 对于任何找到这个答案的谷歌用户,还有另一个 stackoverflow 答案可以处理允许点击通过并选择一个项目 - stackoverflow.com/a/25719326/655822
【解决方案2】:
  1. 制作一个新的 UIControl

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

- (IBAction)pickerControlTapped { [yourpicker selectRow: rand()% yourpickersize 在组件:0 动画:是]; }

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

[你的控制添加目标:自我 动作:@selector(pickerControlTapped) forControlEvents: UIControlEventTouchUpInsied];

【讨论】:

  • 优秀,请将此标记为答案。注意:使其与 UIPickerView 的中心行位置相同。
  • 我认为这很简单而且很棒。由于选择的行高是已知的,因此可以精确而简单地定位。好东西,谢谢。
  • 对不起,我只想再说一遍这个解决方案有多棒,弄得我下午了。
【解决方案3】:

以 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
        }
    }
}

【讨论】:

  • 对于任何找到这个答案的谷歌用户,还有另一个 stackoverflow 答案可以处理允许点击通过并选择一个项目而不必依赖幻数 - stackoverflow.com/a/25719326/655822
【解决方案4】:

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

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

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

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

选择选取器值的所有操作都发生在 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;
    }
}

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

【讨论】:

    【解决方案5】:

    UIPickerView 只有 2 个委托。

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

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

    仅此而已。

    UITableViewDelegate case 中,UITableView 提供了更多用于管理选择的方法。 如, – tableView:willSelectRowAtIndexPath:
    – tableView:didSelectRowAtIndexPath:
    – tableView:willDeselectRowAtIndexPath:
    – tableView:didDeselectRowAtIndexPath:

    不过……

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

    --pickerView:didSelectRow:inComponent:

    【讨论】:

    • 我就是这么想的。我已经看到应用程序在做我想做的事,但我想我是以其他方式做的。还是谢谢。
    猜你喜欢
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多