UIScrollView prevents touchesBegan, touchesMoved, touchesEnded on view controller

前端 未结 5 1835
一整个雨季
一整个雨季 2020-12-05 07:19

I am handling touches for a couple of my UI components in my view controller (custom subclass of UIViewController). It has methods touchesBegan:withEvent:,

相关标签:
5条回答
  • 2020-12-05 07:39

    "It was working fine. Then I added a scroll view (UIScrollView) as the top view in the hierarchy."

    is your scrollview on top of your contentview that contains items?

    all your components should be in the scrollview and not the view behind the scrollview

    0 讨论(0)
  • 2020-12-05 07:47

    create a subclass of UIScrollView class and override the touchesBegan: and other touch methods as follows:

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    
    // If not dragging, send event to next responder
      if (!self.dragging){ 
        [self.nextResponder touchesBegan: touches withEvent:event]; 
      }
      else{
        [super touchesBegan: touches withEvent: event];
      }
    }
    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    
    // If not dragging, send event to next responder
        if (!self.dragging){ 
         [self.nextResponder touchesMoved: touches withEvent:event]; 
       }
       else{
         [super touchesMoved: touches withEvent: event];
       }
    }
    -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    
      // If not dragging, send event to next responder
       if (!self.dragging){ 
         [self.nextResponder touchesEnded: touches withEvent:event]; 
       }
       else{
         [super touchesEnded: touches withEvent: event];
       }
    }
    
    0 讨论(0)
  • 2020-12-05 07:51

    The touchesBegan: etc methods will NEVER be called in a UIScrollView because it is a subclass of UIView and overrides these methods. check out the different UIScrollView methods available here. The work-around will depend on what you want to implement.

    0 讨论(0)
  • 2020-12-05 07:55

    Well this worked, but I'm not sure I can "get away with it", since nextResponder is not one of the UIView methods you're "encouraged" to override in a subclass.

    @interface ResponderRedirectingView : UIView {
    
        IBOutlet UIResponder *newNextResponder;
    
    }
    
    @property (nonatomic, assign) IBOutlet UIResponder *newNextResponder;
    
    @end
    
    
    @implementation ResponderRedirectingView
    
    @synthesize newNextResponder;
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            // Initialization code
        }
        return self;
    }
    
    - (UIResponder *)nextResponder {
        return self.newNextResponder;
    }
    
    - (void)dealloc
    {
        [super dealloc];
    }
    
    @end
    

    Then in Interface Builder I made the direct subview of the scroll view one of these, and hooked up its newNextResponder to skip the scrollview and point directly to the view controller.

    This works too, replacing the override of nextResponder with these overrides:

    - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        [self.newNextResponder touchesBegan:touches withEvent:event];
    }
    
    - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
        [self.newNextResponder touchesMoved:touches withEvent:event];
    }
    
    - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
        [self.newNextResponder touchesEnded:touches withEvent:event];
    }
    
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
        [self.newNextResponder touchesCancelled:touches withEvent:event];
    }
    
    0 讨论(0)
  • 2020-12-05 08:01

    user1085093's answer worked for me. Once you move the touch more than a small amount, however, it then gets interpreted as a Pan Gesture.

    I overcame this by altering the behaviour of the Pan Gesture recogniser so it requires two fingers:

    -(void)awakeFromNib
    {
        NSArray                 *gestureRecognizers = self.gestureRecognizers;
        UIGestureRecognizer     *gestureRecognizer;
    
        for (gestureRecognizer in gestureRecognizers) {
            if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
                UIPanGestureRecognizer      *pgRecognizer = (UIPanGestureRecognizer*)gestureRecognizer;
                pgRecognizer.minimumNumberOfTouches = 2;
            }
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题