【发布时间】:2011-09-24 08:49:17
【问题描述】:
我敢肯定,有人希望让多个按钮同时接受触摸的原因有很多。但是,我们大多数人一次只需要按下一个按钮(用于导航、以模态方式呈现的内容、呈现弹出框、视图等)。
那么,苹果为什么要将UIButton的exclusiveTouch属性默认设置为NO呢?
【问题讨论】:
标签: iphone xcode ipad uibutton
我敢肯定,有人希望让多个按钮同时接受触摸的原因有很多。但是,我们大多数人一次只需要按下一个按钮(用于导航、以模态方式呈现的内容、呈现弹出框、视图等)。
那么,苹果为什么要将UIButton的exclusiveTouch属性默认设置为NO呢?
【问题讨论】:
标签: iphone xcode ipad uibutton
非常老的问题,但值得 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 属性exclusiveTouch 表示视图(按钮)是该窗口中唯一可以交互的东西,如果它设置为YES。如文档中所述:将此属性设置为 YES 会导致接收器阻止将触摸事件传递到同一窗口中的其他视图。此属性的默认值为 NO。
因此,您可能在一个窗口中有多个按钮或交互控件/视图并希望将exclusiveTouch 设置为NO,这是常见的行为。
如果为窗口中的任何 UIView 子类将此属性设置为 YES,则只要该属性设置为 YES,您就无法与窗口中的其他任何内容进行交互。这意味着,如果您使用 exclusiveTouch = YES 初始化按钮,但也有一个表格视图或另一个按钮或滚动视图或任何其他基于交互的视图,它不会响应任何触摸。
【讨论】:
exclusiveTouch 设置为 NO,然后如果用户同时按下它们,两者都会调用它们的操作方法。如果他们的操作方法由于某种原因发生冲突(比如他们都将不同的视图控制器推送到导航堆栈),应用程序就会崩溃,这就是我的问题。
exclusiveTouch 只是意味着你的 UIButton 下的任何视图都不会接收到触摸事件。
默认设置为 no,因为您通常希望下面的视图接收这些事件。例如,如果您在滚动视图顶部有一个 UIButton 并且用户想要滚动。您希望 scrollView 滚动,即使它们是从手指放在 UIButton 上开始的。
【讨论】:
我刚刚阅读了 iOS 5 的发行说明,从这个版本开始,exclusiveTouch 将默认设置为 YES。所以请记住,它会随着 iOS 的新版本而改变。
【讨论】:
exclusiveTouch默认设置为YES?