UIPickerView,检测“滚轮”启动和停止?

我刚刚发现,如果我做以下事情:

  1. 单击将UIPickerView为动画的按钮
  2. 快速启动滚轮,然后经过最后一个项目
  3. 使用按钮关闭视图

然后它还没有选择最后一个项目。

我只是在触发didSelectRow方法时输出到控制台尝试了这个,并且当方向盘稳定在最后一个项目时它会触发。

我可以检测到车轮仍然在滚动,这样我可以延迟检查它是否有选定值,直到它稳定下来?

如果重要的是,我正在使用MonoTouch进行编程,但如果您有一个代码示例,我可以很好地阅读Objective-C代码以重新实现它。

我想你可以检查一下UIPickerView是否处于动画中并等待它停止。 这是在这里回答的链接

由于动画键不起作用,我编写了这个简单的函数,用于检测UIPickerView当前是否正在移动。

 -(bool) anySubViewScrolling:(UIView*)view { if( [ view isKindOfClass:[ UIScrollView class ] ] ) { UIScrollView* scroll_view = (UIScrollView*) view; if( scroll_view.dragging || scroll_view.decelerating ) { return true; } } for( UIView *sub_view in [ view subviews ] ) { if( [ self anySubViewScrolling:sub_view ] ) { return true; } } return false; } 

它最终返回真正的五个级别。

由于animationKeys似乎不再起作用,我有另一个解决方案。 如果检查UIPickerView的子视图,您将看到每个组件都有一个UIPickerTableView

这个UIPickerTableView确实是UITableView的子类,当然还有UIScrollView的子类。 因此,您可以检查其contentOffset值以检测差异。

此外,它的scrollViewDelegate默认为nil,所以我假设你可以安全地设置你的对象来检测scrollViewWillBeginDraggingscrollViewDidEndDecelerating等。

通过保持对每个UIPickerTableView的引用,您应该能够实现有效的isWheelRolling方法。

扩展了@iluvatar_GR的答案

 extension UIView { func isScrolling () -> Bool { if let scrollView = self as? UIScrollView { if (scrollView.isDragging || scrollView.isDecelerating) { return true } } for subview in self.subviews { if ( subview.isScrolling() ) { return true } } return false } func waitTillDoneScrolling (completion: @escaping () -> Void) { var isMoving = true DispatchQueue.global(qos: .background).async { while isMoving == true { isMoving = self.isScrolling() } DispatchQueue.main.async { completion()} } } } 

Swift版本扩展了@DrainBoy答案

 extension UIView { func isScrolling () -> Bool { if let scrollView = self as? UIScrollView { if (scrollView.dragging || scrollView.decelerating) { return true } } for subview in self.subviews { if ( subview.isScrolling() ) { return true } } return false } } 

扩展@iluvatar_GR,@ Robert_at_Nextgensystems回答

使用Gesture,UIScrollView isDragging或isDecelerating。

 // Call it every time when Guesture action. @objc func respondToSwipeGesture(gesture: UIGestureRecognizer) { // Changes the button name to scrolling at the start of scrolling. DispatchQueue.main.async { self._button.setTitle("Scrolling...", for: .normal) self._button.isEnabled = false self._button.backgroundColor = Utils.hexStringToUIColor(hex: "FF8FAE") } // Indication according to scrolling status _datePicker.waitTillDoneScrolling(completion: { print("completion") DispatchQueue.main.async { self._button.setTitle("Completion", for: .normal) self._button.isEnabled = true self._button.backgroundColor = Utils.hexStringToUIColor(hex: "7CB0FF") } }) } 

[SWIFT4]分享示例源链接!

输入Sample Source链接

  • 参考: 如何识别所有4个方向的滑动

您可以在选择器上使用SwipeGestureRecognizer。 我认为这根本不是一个完美的解决方案。

 - (void)viewDidLoad { [super viewDidLoad]; _pickerSwipeGestureRecognizer.delegate = self; [_pickerSwipeGestureRecognizer setDirection:(UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp)]; } - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{ if([gestureRecognizer isEqual:_pickerSwipeGestureRecognizer]){ NSLog(@"start"); } } - (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { NSLog(@"end"); }