Pan Objects in UIScrollView

I am working on an application in which I have several UIView objects that are subviews in a UIScrollView object. I create subviews programmatically and put them in a scroll view according to the properties of related objects. The user can move these objects as a scroll. This usually works, but sometimes scrollview captures a panorama gesture.

What I would like to do is turn off the gesture recognizer of the scroll view if the location of the touch is inside one of the subzones.

I can find the gesture recognizer of the scroll view by looking at the scroll array of the gesture recognizers and looking for the object UIScrollViewPanGestureRecognizer. I guess there can only be one.

The idea I have is that my view controller be a delegate of this gesture recognizer, and then the delegate suppresses it if the touch is within one of the subzones.

Is this the best way to handle this scenario or is there a better way?

I did something similar described in my answer to my own question here. How to get stepper and longpress for coexistence?

Hmmm. It seems like it will be harder than I expected to learn scrollview UIScrollViewPanGestureRecognizer. Any hints of this would be appreciated.

My idea is not working. To encode my idea, I had to make my VC a scrollview gesture recognizer delegate. However, when I do this, I get this error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UIScrollView built-in pan gesture recognizer must have its scroll view as its delegate.'

, . viewDidLoad , scrollview pan self (self.scrollViewPanGestureRecognizer - ):

self.scrollViewPanGestureRecognizer = [self.scrollView panGestureRecognizer];
self.scrollViewPanGestureRecognizer.delegate = self;

:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
   //Disable touch if touch location is in a subview.
   BOOL enableGestureRecognizer = YES;

   if (gestureRecognizer == self.scrollViewPanGestureRecognizer) {
      CGPoint touchLocation = [touch locationInView:self.scrollView];
      for (UIView *s in self.scrollView.subviews) {
         if (CGRectContainsPoint(s.frame, touchLocation)) {
            enableGestureRecognizer = NO;
         }
      }
   }
   return enableGestureRecognizer;
}

, , , VC .

scrollEnabled NO . , . - . , , , - , . . .

UPDATE: . , , , , . , , , 320 . -, - . , .

viewDidLayoutSubviews. :

self.view.frame             is {{0, 0}, {480, 320}} 
self.view.bounds            is {{0, 0}, {480, 320}} 
self.scrollView.frame       is {{0, 0}, {480, 320}} 
self.scrollView.bounds      is {{0, 0}, {480, 320}}
self.scrollView.contentSize is {480, 320}

, - . ?

+4
4

. , . , scrollview, . :

self.view
    scroll view
        UIView (fills whole scroll view)
            subview1
            subview2
            subviewn

UIView, . .

UIView , - . , .

, , , , , .

+1

requireGestureRecognizerToFail: .

, (scrollViewGesture) , . , subView (subViewGesture),

scrollViewGesture.requireGestureRecognizerToFail =subViewGesture;
+3

-, . - :

touchesShouldBegin:withEvent:inContentView:, pagingEnabled touchesShouldCancelInContentView: ( ), .

0

: , , touchesBegan, touchesMove touchesEnded . , , , .

You need to disable user interaction in subzones, disable scrolling in scrolling and directly change scrollview contentOffset.

-1
source

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


All Articles