UIScrollview窃取触摸事件

时间:2013-12-03 04:12:19

标签: ios iphone objective-c uiview uiscrollview

我有一个实现UIView的子类touchesBegan, touchesMoved, touchesEnded。一切都运作良好。然后,我将UIScrollview作为子视图添加到此UIVIew。在UIScrollview内进行的触摸是not forwarded back up the responder chain to the parent view,因此我的UIView的触摸方法永远不会被调用(它们被称为在scrollview之外进行的触摸就好了。)

我创建了一个新的UIScrollView类别:

@implementation UIScrollView (forwardTouches)

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    // If not dragging, send event to next responder
    if (!self.dragging){
        [self.nextResponder touchesBegan: touches withEvent:event];
        [self setScrollEnabled:NO];
        NSLog(@"touchesBegan");
    }
    else{
        NSLog(@"touchesBegan-else");
        [super touchesEnded: 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];
        NSLog(@"touchesMoved");
    }
    else{
        NSLog(@"touchesMoved - else");
        [super touchesEnded: 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];
        [self setScrollEnabled:YES];
        NSLog(@"touchesEnded");
    }
    else{
        NSLog(@"touchesEnded - else");
        [super touchesEnded: touches withEvent: event];
    }
}

这实际上似乎在iPhone上有效(如果用户将手指拖过滚动视图,它会滚动,但是如果他将它放在视图上并且不移动它,则父视图的touchesBegan方法火灾),但它不适用于iPad。据推测,self.dragging需要更多的时间在iPad上,但我正在努力想办法可靠地解决这个问题。我确定我错过了一些非常明显的东西。提前谢谢!

编辑可能的解决方案:

经过一些试验和错误,我想出了下面的代码。它似乎在iPhone和iPad上运行良好。使用它的任何原因都可能是一个坏主意?

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    NSArray * myDataArray = [NSArray arrayWithObjects:touches, event, nil];

    // If not dragging, send event to next responder
    if (!self.dragging){
        [self performSelector:@selector(forwardTouches:) withObject:myDataArray afterDelay:0.5];
    }
    else{
        NSLog(@"touchesBegan-else");
        [super touchesEnded: touches withEvent: event];
        [NSObject cancelPreviousPerformRequestsWithTarget:self];
    }
}

-(void)forwardTouches:(NSArray *)array{
    NSSet * mySet = [array objectAtIndex:0];
    UIEvent * myEvent = [array objectAtIndex:1];

    if (!self.dragging){
        [self.nextResponder touchesBegan:mySet withEvent: myEvent];
        [self setScrollEnabled:NO];
    }
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

    // If not dragging, send event to next responder
    if (!self.dragging){
        [self.nextResponder touchesMoved: touches withEvent:event];
        NSLog(@"touchesMoved");
    }
    else{
        NSLog(@"touchesMoved - else");
        [super touchesEnded: touches withEvent: event];
        [NSObject cancelPreviousPerformRequestsWithTarget:self];
    }
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

    // If not dragging, send event to next responder
    if (!self.dragging){
        [self.nextResponder touchesEnded: touches withEvent:event];
        [self setScrollEnabled:YES];
        NSLog(@"touchesEnded");
    }
    else{
        NSLog(@"touchesEnded - else");
        [super touchesEnded: touches withEvent: event];
        [NSObject cancelPreviousPerformRequestsWithTarget:self];
    }
}

1 个答案:

答案 0 :(得分:0)

上面的代码不是一个好的计划。 如果你想超级视图有机会处理子视图中出现的触摸,你应该使用手势,而不是改变触摸的转发,这是危险的。