UIScrollView阻止视图控制器上的touchesBegan touchesMoved touchesEnded



我正在处理触摸我的几个UI组件在我的视图控制器(UIViewController的自定义子类)。它有方法touchesBegan:withEvent:, touchesMoved:withEvent:touchesEnded:withEvent:。它工作得很好。然后我添加了一个滚动视图(UIScrollView)作为层次结构中的顶部视图。

现在视图控制器上的触摸处理程序不起作用了。他们没有接到电话。有趣的是,我在滚动视图中有很多其他的UI组件。有些是按钮,有些是定义自己的touchesBegan:withEvent:的自定义视图,等等。唯一不能工作的是视图控制器上的触摸处理程序。

我想也许是因为滚动视图为自己的目的拦截那些触摸,但我子类化了UIScrollView,只是为了看看我是否能让它工作,我总是从touchesShouldBegin:withEvent:inContentView:NO总是从touchesShouldCancelInContentView:返回YES。还是不行

如果它有区别,我的视图控制器在标签栏控制器内,但我不认为这是相关的。

有人遇到这个问题并有现成的解决方案吗?我猜是滚动视图在响应器链上。我能把它弄回去吗?我想如果我想不出别的办法我就把滚动视图下的顶层视图设为自定义视图并将消息转发给视图控制器,但似乎很笨拙

创建一个UIScrollView类的子类,并重写touchesBegan:和其他触摸方法,如下所示:

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

这是有效的,但我不确定我能"摆脱它",因为nextResponder不是你"鼓励"在子类中重写的UIView方法之一。

@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

然后在Interface Builder中,我将滚动视图的直接子视图作为其中之一,并连接它的newNextResponder以跳过滚动视图并直接指向视图控制器。

这也可以,用这些重写替换nextResponder的重写:

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

"一切正常。然后我添加了一个滚动视图(UIScrollView)作为层次结构中的顶部视图。"

你的scrollview是否位于包含项目的contentview之上?

所有组件都应该在scrollview中,而不是在scrollview后面的视图中

user1085093的回答对我有效。然而,一旦你移动触摸超过一个小的量,它就会被解释为一个平移手势。

我通过改变平移手势识别器的行为来克服这个问题,所以它需要两个手指:

-(void)awakeFromNib
{
    NSArray                 *gestureRecognizers = self.gestureRecognizers;
    UIGestureRecognizer     *gestureRecognizer;
    for (gestureRecognizer in gestureRecognizers) {
        if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
            UIPanGestureRecognizer      *pgRecognizer = (UIPanGestureRecognizer*)gestureRecognizer;
            pgRecognizer.minimumNumberOfTouches = 2;
        }
    }
}

touchesBegan:等方法将永远不会UIScrollView中被调用,因为它是UIView的子类并且覆盖了这些方法。在这里查看不同的UIScrollView方法。解决方法将取决于您想要实现的内容。

相关内容

  • 没有找到相关文章

最新更新