【问题标题】:Is there a way to pass touches through on the iPhone?有没有办法在 iPhone 上通过触摸?
【发布时间】:2010-10-12 11:58:06
【问题描述】:

我有几个UIButtons,用于设置在主区域中点击时的当前操作。我还想允许用户从按钮直接拖动到主区域并采取相同的操作;本质上,touchesBegan 和 touchesMoved 应该在触摸 UIButtons 时传递给主视图,但也应该发送按钮按下动作。

现在,我在更改控件内部进行了润色。拖拽退出调用touch up inside部分设置控件,然后调用touches begin部分开始主区域触摸操作。

但是,此时,touchesMoved 和 touchesEnded 显然没有被调用,因为触摸源自 UIButton。

有没有办法半忽略触摸以便将它们传递到主区域,但也允许我先设置控件?

【问题讨论】:

    标签: iphone cocoa-touch


    【解决方案1】:

    我知道这个问题已经有两年的历史了(并且已经回答了),但是……

    当我自己尝试时,触摸被转发,但按钮不再像按钮那样表现。我也将触摸传递给“超级”,现在一切都很好。

    因此,对于可能偶然发现此问题的初学者,代码应如下所示:

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {  
        [super touchesBegan:touches withEvent:event];
        [self.nextResponder touchesBegan:touches withEvent:event]; 
    }
    

    【讨论】:

    • 太棒了!我遇到了完全相同的问题,这解决了它!点赞!
    • 这个方法会在 UIButton 的子类中吗?
    • 是的,它会在 UIButton 的子类中使用。
    • 谢谢。当我跟踪变量中的触摸次数时。我发现相应地您需要对 touchesEnded 和 touchesCancelled 以及您需要的任何其他内容执行相同的操作。
    • 如果这是 UITextfield 的子类.. 是同一个过程吗?
    【解决方案2】:

    在文档中,查找Responder Objects and the Responder Chain

    您可以通过将触摸转发到响应者链来在对象之间“共享”触摸。 您的 UIButton 有一个接收 UITouch 事件的响应器/控制器,我的猜测是,一旦它对它返回的消息进行了解释 - 触摸已经被处理和处理。

    Apple 建议这样的事情(当然基于触摸的类型):

    [self.nextResponder touchesBegan:touches withEvent:event];

    而不是处理它传递的触摸事件。

    子类 UIButton:

    MyButton.h

    #import <Foundation/Foundation.h>
    
    @interface MyButton : UIButton {
    
    }
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event ;
    
    @end
    

    MyButton.m

    #import "MyButton.h"
    
    @implementation MyButton
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {  
        printf("MyButton touch Began\n");
        [self.nextResponder touchesBegan:touches withEvent:event]; 
    }
    @end
    

    【讨论】:

    • 所以在这种情况下,我想我必须将 UIButton 子类化以传递触摸?
    • 子类化应该是不必要的,你需要稍微探索一下这个链。包含您的按钮的视图或控件将成为链中的下一个响应者。
    • 恐怕我不太明白如何从 UIButton 捕获消息并将它们传递给 UIView 而无需子类化 UIButton 以实际获取消息。
    • 不需要在头文件中声明 touchesBegan:: 方法,因为它只是被覆盖了,对吧?
    • 您在上面有一个指向文档的链接。我一直遇到同样的问题,只是在那些文档中阅读:“如果您实现自定义视图来处理事件或操作消息,则不应将事件或消息直接转发给 nextResponder 以将其发送到响应者链。而是调用当前事件处理方法的超类实现——让 UIKit 处理响应者链的遍历。”
    【解决方案3】:

    也不需要子类!只需将它放在您的实现的顶部,然后再进行其他任何操作:

    #pragma mark PassTouch
    
    @interface UIButton (PassTouch)
    @end
    
    @implementation UIButton (PassTouch)
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [super touchesBegan:touches withEvent:event];
        [self.nextResponder touchesBegan:touches withEvent:event];
    }
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [super touchesMoved:touches withEvent:event];
        [self.nextResponder touchesMoved:touches withEvent:event];
    }
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [super touchesEnded:touches withEvent:event];
        [self.nextResponder touchesEnded:touches withEvent:event];
    }
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [super touchesCancelled:touches withEvent:event];
        [self.nextResponder touchesCancelled:touches withEvent:event];
    }
    @end
    

    【讨论】:

    • 像魅力一样工作 :-) 非常感谢!
    • 顺便说一句,可能仍然需要子类化。例如,如果您需要将确实需要在同一视图中传递触摸的按钮与出于某种原因您不想拥有该功能的按钮混合怎么办?当我第一次尝试这个时,我在 UIButton 上创建了一个类别,但发现由于我上面提到的原因,使用子类更安全,所以我确切知道何时使用转发触摸的按钮。
    • 另外,你应该对touchesCancelled做同样的事情。
    • 我不建议这样做。不能保证先调用类别方法还是默认方法。这可能有效,但这也意味着您在项目中拥有的每个UIButton 都有可能克隆此行为(不受控制)。
    • 正如@walkingbrad 所写,这是个坏主意。类别不打算用于覆盖事物,并且这样做并不可靠。
    猜你喜欢
    • 2019-03-05
    • 2013-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多