我有一个UIPageViewController,它包含几个UIViewControllers。每个UIViewController的视图都有一个子视图:MyUIView。我重写了touchesBegan和MyUIView中的所有其他3种方法。
当我在MyUIView中从上到下滑动时,我得到-touchesMoved:withEvent:调用没有问题,但是当我从左向右滑动时,UIPageViewController滚动,并且在MyUIView中调用了-touchesCancelled:withEvent:。 / p>
我没有在这4种方法中调用[super touchesXXX:withEvent:],我认为这应该会阻止UIPageViewController接收触摸事件,但不知怎的,似乎UIPageViewController识别出滑动,并取消了MyUIView触摸。
我注意到另一个细节,如果我触摸MyUIView并从左向右移动到非常慢的距离,我仍然得到-touchesMoved:withEvent:called。但是在一定距离(可能是10分)之后,UIPageViewController似乎识别出滑动和滚动,同时取消了MyUIView中的触摸。
问题是,发生了什么?如何在MyUIView中使用触摸事件,并停止向上游转发事件?
答案 0 :(得分:0)
使用Xcode"调试视图层次结构"功能,我找到了UIPageViewController.view的视图层次结构:
_UIQueuingScrollView看起来很可疑,所以我记录了它的手势识别器:
2016-10-26 19:02:16.846 LSYReader[5202:293575] _UIQueuingScrollView gesture:<UIScrollViewDelayedTouchesBeganGestureRecognizer: 0x6080001b4f20; state = Possible; delaysTouchesBegan = YES; view = <_UIQueuingScrollView 0x7f884003ba00>; target= <(action=delayed:, target=<_UIQueuingScrollView 0x7f884003ba00>)>>
2016-10-26 19:02:16.848 LSYReader[5202:293575] _UIQueuingScrollView gesture:<UIScrollViewPanGestureRecognizer: 0x7f883e70a240; state = Possible; delaysTouchesEnded = NO; view = <_UIQueuingScrollView 0x7f884003ba00>; target= <(action=handlePan:, target=<_UIQueuingScrollView 0x7f884003ba00>)>; must-fail = {
<UIScrollViewPagingSwipeGestureRecognizer: 0x6080001dc5c0; state = Possible; view = <_UIQueuingScrollView 0x7f884003ba00>; target= <(action=_handleSwipe:, target=<_UIQueuingScrollView 0x7f884003ba00>)>>
}>
2016-10-26 19:02:16.849 LSYReader[5202:293575] _UIQueuingScrollView gesture:<UIScrollViewPagingSwipeGestureRecognizer: 0x6080001dc5c0; state = Possible; view = <_UIQueuingScrollView 0x7f884003ba00>; target= <(action=_handleSwipe:, target=<_UIQueuingScrollView 0x7f884003ba00>)>; must-fail-for = {
<UIScrollViewPanGestureRecognizer: 0x7f883e70a240; state = Possible; enabled = NO; delaysTouchesEnded = NO; view = <_UIQueuingScrollView 0x7f884003ba00>; target= <(action=handlePan:, target=<_UIQueuingScrollView 0x7f884003ba00>)>>
}>
然后,我禁用了这些手势识别器,现在MyUIView中的一切正常。
[_pageViewController.view.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isKindOfClass:NSClassFromString(@"_UIQueuingScrollView")]) {
[obj.gestureRecognizers enumerateObjectsUsingBlock:^(__kindof UIGestureRecognizer * _Nonnull obj1, NSUInteger idx1, BOOL * _Nonnull stop1) {
if ([obj1 isKindOfClass:NSClassFromString(@"UIScrollViewDelayedTouchesBeganGestureRecognizer")]) {
obj1.enabled = NO;
} else if ([obj1 isKindOfClass:NSClassFromString(@"UIScrollViewPanGestureRecognizer")]) {
obj1.enabled = NO;
} else if ([obj1 isKindOfClass:NSClassFromString(@"UIScrollViewPagingSwipeGestureRecognizer")]) {
obj1.enabled = NO;
}
}];
}
}];