UIPickerView, detect rolling wheel, start and stop?

I just found that if I do the following:

  • Click the button that animates the UIPickerView in my view
  • Quickly start the rotation of the wheel, and then past, the last element
  • Reject View with Button

Then he has not yet selected the last item.

I tried this by simply outputting to the console whenever the didSelectRow method was didSelectRow , and it fires when the wheel stabilizes in the last paragraph.

Can I find that the wheel is still rolling, so that I can defer its check to the selected value until it stabilizes?

If that matters, I program in MonoTouch, but I can read Objective-C code well enough to override it if you have sample code.

+4
source share
7 answers

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

-one
source

Since the animation keys do not work, I wrote this simple function that works to detect if the UIPickerView is 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 truth to five levels.

+7
source

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

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

Also, its scrollViewDelegate is zero by default, so I assume that you can safely set your object to detect scrollViewWillBeginDragging , scrollViewDidEndDecelerating , etc.

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

+3
source

Extended answer @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()} } } } 
+2
source

Swift version with @DrainBoy extension is responsible

 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 } } 
+1
source

Extension @iluvatar_GR, @Robert_at_Nextgensystems answer

Used by 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 Link Link Source!

enter source source link

+1
source

You can use SwipeGestureRecognizer on the collector. I guess this is not an ideal solution.

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

Source: https://habr.com/ru/post/1395503/


All Articles