UIPicker检测当前所选行的点击

Roy*_*yce 39 iphone select tap touch uipickerview

我有一个UIPickerView和,didSelectRow当点击选定的行时不调用该方法.我需要处理这个案子.有任何想法吗?

Nik*_*kov 24

首先,使类符合UIGestureRecognizerDelegate协议

然后,在视图设置中:

UITapGestureRecognizer *tapToSelect = [[UITapGestureRecognizer alloc]initWithTarget:self
                                                                                 action:@selector(tappedToSelectRow:)];
tapToSelect.delegate = self;
[self.pickerView addGestureRecognizer:tapToSelect];
Run Code Online (Sandbox Code Playgroud)

其他地方:

#pragma mark - Actions

- (IBAction)tappedToSelectRow:(UITapGestureRecognizer *)tapRecognizer
{
    if (tapRecognizer.state == UIGestureRecognizerStateEnded) {
        CGFloat rowHeight = [self.pickerView rowSizeForComponent:0].height;
        CGRect selectedRowFrame = CGRectInset(self.pickerView.bounds, 0.0, (CGRectGetHeight(self.pickerView.frame) - rowHeight) / 2.0 );
        BOOL userTappedOnSelectedRow = (CGRectContainsPoint(selectedRowFrame, [tapRecognizer locationInView:self.pickerView]));
        if (userTappedOnSelectedRow) {
            NSInteger selectedRow = [self.pickerView selectedRowInComponent:0];
            [self pickerView:self.pickerView didSelectRow:selectedRow inComponent:0];
        }
    }
}

#pragma mark - UIGestureRecognizerDelegate

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • 为了使这个代码工作,我添加了 - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer {// return return true; }如下所示:http://stackoverflow.com/questions/22319427/ios-7-1-uitapgesture-not-working-with-uipickerview?lq = 1 (2认同)

Ele*_*gyD 12

尼古拉在Swift 4中的回答:

首先,添加一个UITapGestureRecognizer到您的UIPickerViewin viewDidLoad()并让你UIViewController符合UIGestureRecognizerDelegate.

let tap = UITapGestureRecognizer(target: self, action: #selector(pickerTapped))
tap.delegate = self
self.pickerView.addGestureRecognizer(tap)
Run Code Online (Sandbox Code Playgroud)

添加此函数,在检测到某行时调用您的UIPickerViewDelegate:

@objc func pickerTapped(tapRecognizer: UITapGestureRecognizer) {
    if tapRecognizer.state == .ended {
        let rowHeight = self.pickerView.rowSize(forComponent: 0).height
        let selectedRowFrame = self.pickerView.bounds.insetBy(dx: 0, dy: (self.pickerView.frame.height - rowHeight) / 2)
        let userTappedOnSelectedRow = selectedRowFrame.contains(tapRecognizer.location(in: self.pickerView))
        if userTappedOnSelectedRow {
            let selectedRow = self.pickerView.selectedRow(inComponent: 0)
            pickerView(self.pickerView, didSelectRow: selectedRow, inComponent: 0)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

添加shouldRecognizeSimultaneouslyWith方法UIGestureRecognizerDelegate:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*ani 10

尼古拉对斯威夫特的回答:

let tap = UITapGestureRecognizer(target: self, action: #selector(OCAccountSettingsViewController.pickerTapped(_:)))
tap.cancelsTouchesInView = false
tap.delegate = self
pickerView.addGestureRecognizer(tap)
Run Code Online (Sandbox Code Playgroud)

重要的是让你的viewController确认UIGestureRecognizerDelegate,否则处理程序将不会触发:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true}
Run Code Online (Sandbox Code Playgroud)

最后一步将是tap事件的处理程序:

func pickerTapped(tapRecognizer:UITapGestureRecognizer)
{
    if (tapRecognizer.state == UIGestureRecognizerState.Ended)
    {
      let rowHeight : CGFloat  = self.pickerView.rowSizeForComponent(0).height
      let selectedRowFrame: CGRect = CGRectInset(self.pickerView.bounds, 0.0, (CGRectGetHeight(self.pickerView.frame) - rowHeight) / 2.0 )
      let userTappedOnSelectedRow = (CGRectContainsPoint(selectedRowFrame, tapRecognizer.locationInView(pickerView)))
      if (userTappedOnSelectedRow)
      {
        let selectedRow = self.pickerView.selectedRowInComponent(0)
        //do whatever you want here
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)


小智 5

使用iOS 4.2/4.3时,解决方案touchesBegan:/ touchesEnded:工作正常,但他们停止使用iOS.最后,我得到了这个可能有用的解决方案:使用轻敲手势识别.

    IBOutlet UIPickerView *picker;

    [picker addGestureRecognizer:
        [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pickerTapped:)] autorelease]
    ];
Run Code Online (Sandbox Code Playgroud)

在这种情况下,当用户点击选择器视图时,选择器

    -(void)pickerTapped:(UIGestureRecognizer *)gestureRecognizer
Run Code Online (Sandbox Code Playgroud)

被调用.在iOS 4.2+/5.0上为我工作


小智 0

我通过子类化公共超级视图并在发送触摸事件之前拦截它们来解决这个问题。在界面生成器中,我还在选择器区域所在的位置添加了一个按钮,将一个操作附加到触摸事件,并将按钮发送到“后面”(这非常重要,因此它不会在 hitTest 中返回自身)。最相关的代码如下。它可以针对更复杂的情况(例如多点触控)进行改进。

    @implementation InterceptorView


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
 UITouch *t=[touches anyObject];
 CGPoint p=[t locationInView:button];
 if ([button hitTest:p withEvent:event]) 
  started_in_button=YES;
 [hitView touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
 [hitView touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
 UITouch *t=[touches anyObject];
 CGPoint p=[t locationInView:button];
 if ([button hitTest:p withEvent:event] && started_in_button) {
  started_in_button=NO;
  [button sendActionsForControlEvents:UIControlEventTouchUpInside];
 }
 [hitView touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
 [hitView touchesCancelled:touches withEvent:event];
}

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
 hitView = [super hitTest:point withEvent:event];
 return self;
}
Run Code Online (Sandbox Code Playgroud)