【问题标题】:Why isn't UIButton's exclusiveTouch property set to YES by default?为什么UIButton的exclusiveTouch属性默认不设置为YES?
【发布时间】:2011-09-24 08:49:17
【问题描述】:

我敢肯定,有人希望让多个按钮同时接受触摸的原因有很多。但是,我们大多数人一次只需要按下一个按钮(用于导航、以模态方式呈现的内容、呈现弹出框、视图等)。

那么,苹果为什么要将UIButtonexclusiveTouch属性默认设置为NO呢?

【问题讨论】:

    标签: iphone xcode ipad uibutton


    【解决方案1】:

    非常老的问题,但值得 IMO 澄清。

    尽管 Apple 的方法文档非常具有误导性,设置了 ExclusiveTouch 的视图“A”将阻止其他视图接收事件只要 A 自己处理某些事件(例如设置一个带有exclusiveTouch 的按钮并将手指放在它上面,这将阻止与窗口中的其他视图进行交互,但是一旦从exlusiveTouch-item 中移除手指,与它们的交互将遵循通常的模式。

    另一个效果是,只要与其他视图交互,视图 A 就无法接收事件(按住未设置 ExclusiveTouch 的按钮,并且具有 ExclusiveTouch 的按钮也将无法接收事件)。

    您仍然可以将视图中的按钮设置为 ExclusiveTouch 并与其他按钮进行交互,但不能同时进行,因为这个简单的测试 UIViewController 将证明(一旦在 IB 中为 Outlets 和 Actions 设置了正确的绑定) :

    #import "FTSViewController.h"
    
    @interface FTSViewController ()
    - (IBAction)button1up:(id)sender;
    - (IBAction)button2up:(id)sender;
    - (IBAction)button1down:(id)sender;
    - (IBAction)button2down:(id)sender;
    
    @property (nonatomic, strong) IBOutlet UIButton *button1, *button2;
    @end
    
    @implementation FTSViewController
    
    - (IBAction)button1up:(id)sender {
        NSLog(@"Button1 up");
    }
    
    - (IBAction)button2up:(id)sender {
        NSLog(@"Button2 up");
    }
    
    - (IBAction)button1down:(id)sender {
        NSLog(@"Button1 down");
    }
    
    - (IBAction)button2down:(id)sender {
        NSLog(@"Button2 down");
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Guarantees that button 1 will not receive events *unless* it's the only receiver, as well as
        // preventing other views in the hierarchy from receiving touches *as long as button1 is receiving events*
        // IT DOESN'T PREVENT button2 from being pressed as long as no event is being intercepted by button1!!!
        self.button1.exclusiveTouch = YES;
        // This is the default. Set for clarity only
        self.button2.exclusiveTouch = NO;
    }
    @end
    

    鉴于此,恕我直言,Apple 不将每个 UIView 子类的 ExclusiveTouch 设置为 YES 的唯一充分理由是,它会使复杂手势的实现成为真正的 PITA,可能包括我们已经习惯的一些手势在复合 UIView 子类(如 UIWebView)中,将选定视图设置为 ExclusiveTouch=NO(如按钮)比在几乎所有内容上执行递归 ExclusiveTouch=YES 更快,以启用多点触控。

    这样做的缺点是,在许多情况下,UIButtons 和 UITableViewCells(以及其他......)的反直觉行为可能会引入奇怪的错误并使测试更加棘手(就像我在 10 分钟前发生的那样? :( )。

    希望对你有帮助

    【讨论】:

    • 我刚刚创建了一个 UIView 类别,它为所有 UIView 设置了 ExclusiveTouch YES 并且没有任何问题
    • @jjxtra 怎么做,重写哪个方法?
    • 我相信他创建了一个 UIView 的子类,并在 init 方法中将 ExclusiveTouch 设置为 Yes。对我来说真的不起作用,因为我正在寻找一种简单的方法来为我的项目中的所有视图进行独家触摸,而无需在许多地方复制粘贴相同的东西(我很懒:p)
    【解决方案2】:

    UIView 属性exclusiveTouch 表示视图(按钮)是该窗口中唯一可以交互的东西,如果它设置为YES。如文档中所述:将此属性设置为 YES 会导致接收器阻止将触摸事件传递到同一窗口中的其他视图。此属性的默认值为 NO。

    因此,您可能在一个窗口中有多个按钮或交互控件/视图并希望将exclusiveTouch 设置为NO,这是常见的行为。

    如果为窗口中的任何 UIView 子类将此属性设置为 YES,则只要该属性设置为 YES,您就无法与窗口中的其他任何内容进行交互。这意味着,如果您使用 exclusiveTouch = YES 初始化按钮,但也有一个表格视图或另一个按钮或滚动视图或任何其他基于交互的视图,它不会响应任何触摸。

    【讨论】:

    • 假设我有 2 个按钮作为同一视图的子视图。如果我没有在两个按钮上将exclusiveTouch 设置为 NO,然后如果用户同时按下它们,两者都会调用它们的操作方法。如果他们的操作方法由于某种原因发生冲突(比如他们都将不同的视图控制器推送到导航堆栈),应用程序就会崩溃,这就是我的问题。
    • Jesse:您的解释与文档一致,所以这不是您的错,但由于原始文档误导了 IMO,您仍然提供虚假信息:exlusiveTouch doens't prevent 触摸视图中其他按钮的事件(正如您的解释和文档似乎暗示的那样),它只是阻止其他视图接收事件而具有 ExclusiveTouch 的视图正在处理一些(以及如果其他视图也在处理某些事件,则阻止 exlusiveTouch 视图接收事件......)
    • 同样不正确 - 文档具有误导性。更正:“导致接收器阻止触摸事件的传递如果它当前正在接收触摸事件本身”。要进行测试运行并证明此答案是错误的,请设置一个带有两个按钮的 xib,两个记录两条不同消息的 IBAction,在 viewDidLoad 中设置两个按钮上的 setExclusiveTouch:YES。使用“alt + click”在模拟器上进行多点触控并点击两个按钮(使用 shift 键使多点触控控制居中)。您可以在每个按钮上单独进行交互,但不能使用多点触控(但如果您设置了 ExclusiveTouch:NO,则可以)
    【解决方案3】:

    exclusiveTouch 只是意味着你的 UIButton 下的任何视图都不会接收到触摸事件。

    默认设置为 no,因为您通常希望下面的视图接收这些事件。例如,如果您在滚动视图顶部有一个 UIButton 并且用户想要滚动。您希望 scrollView 滚动,即使它们是从手指放在 UIButton 上开始的。

    【讨论】:

    • 我认为这不准确,@Jesse 说得对。将此属性设置为 YES 会导致接收器阻止将触摸事件传递到同一窗口中的其他视图。
    • 它不是那样工作的(尽管文档是这样说的):标志的唯一作用是保证其他视图不会同时收到触摸事件旗帜的所有者(或多或少)。我确实对此进行了测试:有关详细信息,请参阅我的答案。
    • 只是反映我上方的 cmets - 这不是此属性如何影响视图。如果用户积极参与,它将阻止其他视图的交互。如果未触摸 ExclusiveTouch 视图,则其他视图(以及按钮下方的视图)将打开以进行交互。
    【解决方案4】:

    我刚刚阅读了 iOS 5 的发行说明,从这个版本开始,exclusiveTouch 将默认设置为 YES。所以请记住,它会随着 iOS 的新版本而改变。

    【讨论】:

    • 我查了文档,哪里说exclusiveTouch默认设置为YES
    • 这是错误的。来自 iOS 5.1 文档:“此属性的默认值为 NO。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多