【问题标题】:UIView touch handling behavior changed with Xcode 4.2?UIView 触摸处理行为随 Xcode 4.2 改变?
【发布时间】:2011-10-16 20:04:52
【问题描述】:

几天前我将 iPad 升级到 5.0,同时将 Xcode 升级到 4.2,以便继续测试我的应用程序。现在,我在几个与以前版本的 Xcode 一起工作的应用程序中遇到了触摸代码问题。

我继承了 UIImageView 以通过覆盖 -(void)TouchesBegan-(void)TouchesMoved 添加一些拖动功能。我确实没有在子类中覆盖-(void)TouchesEnded,而是在包含图像视图的视图的视图控制器中处理了它。

我将子类 UIImageView 拉到一个新项目中进行测试,并将问题缩小到 UIView(由 Xcode 创建的模板)似乎没有转发触摸事件的事实到视图控制器(也是由 Xcode 创建的)。

如果我将它添加到我的子类中:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touches ended event in ImageToDrag");
    [self.nextResponder touchesEnded:touches withEvent:event];
}

这是我父视图的视图控制器:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touches ended event in ViewController");
}

当我放开正在屏幕上拖动的图像时,我得到了"touches ended event in ImageToDrag",但没有来自视图控制器的日志。

但是,如果我在子类视图中故意跳过视图:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touches ended event in ImageToDrag");
    [[self.nextResponder nextResponder] touchesEnded:touches withEvent:event];
}

然后我得到两个日志条目。

我能想到的唯一解释是,出于某种原因,UIView 正在使用touchesEnded 事件,而不是将其传递给视图控制器。

我已经验证exclusiveTouch 设置为NOuserInteractionEnabled 在父视图和子类UIImageView 上设置为YES

我还测试了 iOS 5.0 和 iOS 4.2 的编译,并将测试应用程序部署到 iOS 5 iPad 和 iOS 4.3.1 iPad。

我能够获得viewController 的触摸事件的唯一方法是跳过视图并在子类中使用双nextResponder。尽管该方法有效,但对我来说似乎是一种 hack,我相信它稍后会回来咬我。

还有其他人看到过这种行为吗?有什么方法可以让我找出UIView 对我的触摸事件做了什么?

谢谢, 丹

【问题讨论】:

    标签: ios ios5 xcode4.2


    【解决方案1】:

    在过去的几个小时里,我一直在努力寻找类似的问题。终于在this post的帮助下解决了

    实际上,看起来我只是设法解决了它,使用来自的提示 https://devforums.apple.com/message/519690#519690
    早些时候,我只是 将 touchesEnded 事件转发给 self.nextResponder。当我添加 具有类似实现的 touchesBegan、Moved、Canceled 处理程序 随着touchesEnded,事件似乎冒泡到根视图 控制器。
    所以我猜在 iOS5 上,视图会丢弃 touchesEnded 事件 当他们还没有看到相关的触摸开始时。

    我不需要添加Moved/etc,我只是在TouchesBegan上转发,然后TouchesEnded又开始工作了!

    【讨论】:

    • 这成功了。关键是我必须在处理完事件后将它们转发到超级视图。另一个注意事项是我必须使用“super”而不是“self.nextResponder”才能让它工作。
    • 感谢您的回答。把我的头发扯掉了。
    【解决方案2】:

    一些触摸处理在 iOS 5.0 中确实有机会;特别是如果您将应用程序重新链接到 5.0 SDK。

    有一节 UIView 的触摸处理方法是这样说的:

    如果您在不调用 super 的情况下重写此方法(一种常用模式),则还必须重写其他用于处理触摸事件的方法,如果只是作为存根(empy)实现。

    所以如果你做一个,你需要做所有。我知道 UIKit 开始采取措施确保 5.0 中的情况如此。

    所以我会从那里开始 - 覆盖视图上的所有方法,看看会发生什么。

    【讨论】:

    • 我在子类中覆盖了 touchesBegan 和 touchesMoved...但不是 touchesCancelled。我会试试看它是否可以清除它。
    • 我也尝试在视图中覆盖 touchesCancelled,但如果不使用双 nextResponder,它仍然无法正常工作。
    猜你喜欢
    • 2011-02-18
    • 2010-12-02
    • 2011-03-23
    • 1970-01-01
    • 2014-06-24
    • 1970-01-01
    • 1970-01-01
    • 2012-01-10
    相关资源
    最近更新 更多