Ios UIPickerView,detect";滚轮;开始和停止?

Ios UIPickerView,detect";滚轮;开始和停止?,ios,xamarin.ios,uipickerview,Ios,Xamarin.ios,Uipickerview,我刚刚发现如果我做了以下事情: 单击将UIPickerView动画设置到我的视图中的按钮 快速启动车轮,朝着最后一个项目滚动,然后越过最后一个项目 用按钮关闭视图 那么它还没有选择最后一项 我试着这样做,只要在启动didSelectRow方法时将其输出到控制台,当控制盘在最后一项上稳定下来时,它就会启动 我是否可以检测到车轮仍在滚动,以便延迟检查所选值,直到车轮稳定 如果它很重要,我在MonoTouch编程,但是如果你有一个代码例子,我可以读ObjultC代码来重新实现它,如果你有一个代码例子,

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

  • 单击将
    UIPickerView
    动画设置到我的视图中的按钮
  • 快速启动车轮,朝着最后一个项目滚动,然后越过最后一个项目
  • 用按钮关闭视图
  • 那么它还没有选择最后一项

    我试着这样做,只要在启动
    didSelectRow
    方法时将其输出到控制台,当控制盘在最后一项上稳定下来时,它就会启动

    我是否可以检测到车轮仍在滚动,以便延迟检查所选值,直到车轮稳定


    如果它很重要,我在MonoTouch编程,但是如果你有一个代码例子,我可以读ObjultC代码来重新实现它,如果你有一个代码例子,

    我想你可以检查UpIKEVIEW是否在动画的中间,并等待它停止。这里回答了这个问题

    因为
    动画键
    似乎不再工作了,我有另一个解决方案。如果检查
    UIPickerView
    的子视图,您将看到每个组件都有一个
    UIPickerTableView

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

    此外,它的
    scrollViewDelegate
    默认为零,因此我假设您可以安全地设置一个对象来检测
    scrollViewWillBeginDragging
    ScrollViewDiEndDecking
    ,等等


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

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

    - (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");
    }
    

    由于动画关键点不起作用,我编写了这个简单的函数,用于检测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;
    }
    
    它最终返回真正的五级深度。

    Swift 4(更新版)版本,扩展了@DrainBoy answers

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

    扩展@iluvatar\u 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()}
    
        }
    }
    }
    

    扩展的@iluvatar\u GR,@Robert\u在下一代系统回答

    使用手势时,UIScrollView为拖拉或减速

    // 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]共享示例源链接

    • 参考:

    您将如何“检查”动画关键点?你能不能提供一个更完整的答案,一个详细阐述这种方法的答案。我看到了你的答案,希望回答一个问题,但我现在带着更多的问题离开。AnimationKeys在2015年似乎不起作用。在我将DrainBoy的代码转换为Swift后,下面的答案对我很有用。太好了,你认为用侦听器模式可以实现吗。我的意思是在选择器开始拖动或减速以及结束时进行监听?至少对于iOS 13上的UIDatePicker来说,“scrollViewDelegate默认为nil”似乎不是这样。重置它会导致禁用它的主要用途