26

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

现在我在视图控制器上的触摸处理程序不起作用。他们不会被召唤。有趣的是,我在滚动视图中有各种其他的 UI 组件可以工作。有些是按钮,有些是定义自己的自定义视图touchesBegan:withEvent:,等等。唯一不起作用的是视图控制器上的触摸处理程序。

我想可能是因为滚动视图为了自己的目的而拦截了这些触摸,但我将 UIScrollView 子类化,只是为了看看我是否可以让它工作,我YES总是从. 还是不行。touchesShouldBegin:withEvent:inContentView:NOtouchesShouldCancelInContentView:

如果它有所不同,我的视图控制器位于标签栏控制器中,但我认为它不相关。

有没有人遇到过这个问题并有现成的解决方案?我的猜测是滚动视图猴子在响应者链上。我可以猴子回来吗?我想如果我想不出其他任何东西,我会让滚动视图下的顶级视图成为自定义视图并将消息转发到视图控制器,但看起来很笨拙。

4

5 回答 5

22

创建 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];
   }
}
于 2012-01-30T09:16:37.303 回答
2

好吧,这行得通,但是我不确定我是否可以“摆脱它”,因为 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];
}
于 2011-09-16T16:23:33.397 回答
0

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

您的滚动视图是否位于包含项目的内容视图之上?

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

于 2011-09-16T01:39:41.413 回答
0

user1085093 的回答对我有用。但是,一旦您移动触摸超过少量,它就会被解释为平移手势。

我通过改变 Pan Gesture 识别器的行为克服了这个问题,因此它需要两个手指:

-(void)awakeFromNib
{
    NSArray                 *gestureRecognizers = self.gestureRecognizers;
    UIGestureRecognizer     *gestureRecognizer;

    for (gestureRecognizer in gestureRecognizers) {
        if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
            UIPanGestureRecognizer      *pgRecognizer = (UIPanGestureRecognizer*)gestureRecognizer;
            pgRecognizer.minimumNumberOfTouches = 2;
        }
    }

}
于 2016-01-24T07:53:02.173 回答
-1

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

于 2011-09-16T16:39:16.260 回答