UIPickerView, detect “rolling wheel” start and stop?

前端 未结 7 1598
悲哀的现实
悲哀的现实 2020-12-18 04:30

I just discovered that if I do the following:

  1. Click the button that animates a UIPickerView into my view
  2. Quickly start the wheel rolling
相关标签:
7条回答
  • 2020-12-18 05:00

    You can use a SwipeGestureRecognizer on the picker. I assume this is not a perfect solution at all.

    - (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");
    }
    
    0 讨论(0)
  • 2020-12-18 05:06

    Swift 4 (updated) version with extension of @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
     }
    }
    
    0 讨论(0)
  • 2020-12-18 05:08

    Expanded @iluvatar_GR, @Robert_at_Nextgensystems answer

    Used Gesture, UIScrollView isDragging or 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] Share Example Source link!

    enter Sample Source link

    • Reference : How to recognize swipe in all 4 directions
    0 讨论(0)
  • 2020-12-18 05:09

    Since animationKeys seems to not work anymore, I have another solution. If you check the subviews of UIPickerView, you'll see that there is a UIPickerTableView for each component.

    This UIPickerTableView is indeed a subclass of UITableView and of course of UIScrollView. Therefore, you can check its contentOffset value to detect a difference.

    Besides, its scrollViewDelegate is nil by default, so I assume you can safely set an object of yours to detect scrollViewWillBeginDragging, scrollViewDidEndDecelerating, etc.

    By keeping a reference to each UIPickerTableView, you should be able to implement an efficient isWheelRolling method.

    0 讨论(0)
  • 2020-12-18 05:11

    I think you can just check if the UIPickerView is in the middle of animating and wait for it to stop. This was answered here link

    0 讨论(0)
  • 2020-12-18 05:15

    As animation keys don't work, I wrote this simple function that works for detecting if a UIPickerView is currently moving.

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

    It ends up returning true five levels deep.

    0 讨论(0)
提交回复
热议问题