10

概述

我正在开发一款 iPhone 游戏,其代码是从另一位开发人员那里继承而来的。游戏网格是一个 UIScrollView,其 contentSize 为 1000x1000。网格包含通过 OpenGL 的 Texture2D 类在屏幕上绘制的多个元素。

UIScrollView 的滚动方向与您手指移动的方向相反。这背后的想法是模拟用手指“筛选”元素的行为,因为触摸路径中的每个元素都应该受到影响/操纵。

 

问题

问题是 UIScrollView 的滚动触发了 touchesCancelled,从而结束了游戏依赖的 touchesMoved 调用来知道要操作哪些元素。即使我的手指移动不会在视觉上触发视图滚动,将手指移动超过 10 个像素的距离也会触发 touchesCancelled 方法,从而结束未来的 touchesMoved 调用,直到我抬起手指并开始新的触摸事件。

我相信触发 touchesCancelled 方法的是滚动事件,因为如果我self.scrollingEnabled = NO;在视图上设置,在屏幕上移动手指会继续触发 touchesMoved,因为无论我在屏幕上移动多远,touchesEnded 都会触发当我抬起手指时按预期调用(在我完成元素筛选之后),并且我的触摸/滑动路径中的每个元素确实是根据需要进行操作的。但是,设置此属性自然会阻止游戏网格的所需滚动。

 

尝试修复失败

我已经尝试self.canCancelContentTouches = NO;在视图的initWithFrame方法中设置,但touchesCancelled仍然被触发,很奇怪。不知道为什么会这样!也许我把它放在了错误的位置,但我不太确定这是否能解决我的问题,因为文档暗示这样的设置无论如何都会阻止滚动:“如果这个属性的值是 NO,一旦内容视图开始跟踪,无论手指移动如何,滚动视图都不会滚动。” 显然这不是我所追求的行为,因此该属性似乎并不是我感兴趣的东西。虽然我仍然对为什么它仍然滚动和调用感到困惑touchesCancelled,但我离题了。

我还添加了该方法- (BOOL)touchesShouldCancelInContentView:(UIView *)view,但它没有被调用,即使没有像文档所说的那样将 canCancelTouches 属性设置self.canCancelContentTouches = NO;为 NO 确实会阻止调用 touchesShouldCancelInContentView 方法:“如果值为canCancelContentTouches 属性为 NO。” . 尽管文档似乎不清楚从该方法返回 NO 是否也会阻止像canCancelContentTouches = NO;设置会。如果不是,那么这将是理想的解决方案。尽管如此,我还是不知道为什么这个方法甚至没有被调用,因为文档只提到了一个阻止它被调用的属性/设置,即使该属性没有设置为 NO,它仍然没有被调用(因此默认为 YES)。

 

我从这里去哪里?

所以现在我很茫然。事实上,在视图开始滚动后,我仍然需要 touchesMoved 才能继续被调用。这有可能吗?如果没有,我在这里有什么选择?

4

2 回答 2

9

我遇到了完全相同的问题(并且浪费了很多时间)。然后我尝试尽快设置该cancelsTouchesInView属性(我在其中完成了viewDidLoad)......它对我有用(如图所示)!

- (void)viewDidLoad {
    [super viewDidLoad];
    /* other initializations */
    scrollView.panGestureRecognizer.cancelsTouchesInView = NO;
}

这适用于 iOS 5。在 iOS 5 之前,您需要遍历所有识别器,找到 panGestureRecognizer,然后设置属性。所以这应该是一个通用的解决方案:

- (void)viewDidLoad {
    [super viewDidLoad];
    /* other initializations */
    for (UIGestureRecognizer *gesture in scrollView.gestureRecognizers){
        if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]){
        gesture.cancelsTouchesInView = NO;    
    }
}
于 2011-12-05T09:33:14.130 回答
0
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated 

这可能会奏效....任何 touchesMoved 都可以触发一个方法,该方法将以与屏幕中心(或其他任何地方)和最后记录的触摸位置之间的距离成比例的速度滚动,直到 touchesEnded。

于 2011-03-10T17:37:00.310 回答