我的应用程序有几个触发不同事件的按钮。用户不应该按住几个按钮。无论如何,按住几个按钮会使应用程序崩溃。
所以,我正在尝试在我的应用中禁用多点触控。
我在所有xib文件中取消选中'Multiple Touch',并且据我所知,属性'multipleTouchEnabled'和'exclusiveTouch'控制视图是否使用多点触控。所以在我的applicationDidFinishLaunching中我已经说过:
self.mainViewController.view.multipleTouchEnabled=NO;
self.mainViewController.view.exclusiveTouch =YES;
在我的每个视图控制器中,我都将它放在viewDidLoad
中self.view.multipleTouchEnabled=NO;
self.view.exclusiveTouch=YES;
然而,仍然接受多次触摸。我可以做一些事情,比如在触发事件后禁用其他按钮,但这将是一个丑陋的黑客。当然有一种方法可以正确禁用多点触控吗?
答案 0 :(得分:44)
如果一次只需要一个按钮来响应触摸,则需要为该按钮设置exclusiveTouch,而不是为父视图设置。或者,当按钮获得“Touch Down”事件时,您可以禁用其他按钮。
这是后者的一个例子,在我的测试中效果更好。为这些按钮设置了exclusiveTouch,但当你将手指从按钮的边缘移开时,却导致了一些有趣的问题,而不是仅仅点击它。
您需要将控制器中的插座连接到每个按钮,然后将“Touch Down”,“Touch Up Inside”和“Touch Up Outside”事件挂钩到控制器中的正确方法。
#import "multibuttonsViewController.h"
@implementation multibuttonsViewController
// hook this up to "Touch Down" for each button
- (IBAction) pressed: (id) sender
{
if (sender == one)
{
two.enabled = false;
three.enabled = false;
[label setText: @"One"]; // or whatever you want to do
}
else if (sender == two)
{
one.enabled = false;
three.enabled = false;
[label setText: @"Two"]; // or whatever you want to do
}
else
{
one.enabled = false;
two.enabled = false;
[label setText: @"Three"]; // or whatever you want to do
}
}
// hook this up to "Touch Up Inside" and "Touch Up Outside"
- (IBAction) released: (id) sender
{
one.enabled = true;
two.enabled = true;
three.enabled = true;
}
@end
答案 1 :(得分:21)
- (void)viewDidLoad {
[super viewDidLoad];
for(UIView* v in self.view.subviews)
{
if([v isKindOfClass:[UIButton class]])
{
UIButton* btn = (UIButton*)v;
[btn setExclusiveTouch:YES];
}
}
}
答案 2 :(得分:5)
- (void)viewDidLoad {
[super viewDidLoad];
for(UIView* v in self.view.subviews)
{
if([v isKindOfClass:[UIButton class]])
{
UIButton* btn = (UIButton*)v;
[btn setExclusiveTouch:YES];
}
}
}
这段代码经过测试,对我来说非常合理。一次按下多个按钮,没有应用程序崩溃。
答案 3 :(得分:3)
如果您想要在整个应用程序中禁用多点触控,并且不想为每个按钮编写代码,那么您只需使用Appearance
按钮即可。写下didFinishLaunchingWithOptions
下面的行。
UIButton.appearance().isExclusiveTouch = true
太棒了!的 UIAppearance 强>
您甚至可以将它用于任何UIView
课程,因此如果您想为少数按钮禁用多点触控。创建一个CustomClass按钮然后
CustomButton.appearance().isExclusiveTouch = true
还有一个优势可以帮到你。如果您想要禁用特定ViewController
UIButton.appearance(whenContainedInInstancesOf: [ViewController2.self]).isExclusiveTouch = true
答案 4 :(得分:3)
基于neoevoke的回答,只是改进了一点,以便它也检查子视图的子项,我创建了这个函数并将其添加到我的utils文件中:
// Set exclusive touch to all children
+ (void)setExclusiveTouchToChildrenOf:(NSArray *)subviews
{
for (UIView *v in subviews) {
[self setExclusiveTouchToChildrenOf:v.subviews];
if ([v isKindOfClass:[UIButton class]]) {
UIButton *btn = (UIButton *)v;
[btn setExclusiveTouch:YES];
}
}
}
然后,简单地致电:
[Utils setExclusiveTouchToChildrenOf:self.view.subviews];
......会做的。
答案 5 :(得分:3)
您的应用因某种原因崩溃了。进一步调查,使用调试器,看看有什么不对,而不是试图隐藏错误。
编辑:
好吧,好吧,我不得不承认我有点苛刻。您必须在每个按钮上设置exclusiveTouch属性。就这样。 multipleTouchEnabled属性无关紧要。答案 6 :(得分:3)
我们的测试人员经常报告这个问题。我有时使用的方法之一,虽然应该有意识地使用,但是为UIView
创建类别,就像这样:
@implementation UIView (ExclusiveTouch)
- (BOOL)isExclusiveTouch
{
return YES;
}
答案 7 :(得分:2)
要在SWIFT中禁用多点触控:
首先需要为每个按钮设置一个插座,然后将专属触摸设置为true。因此,viewDidLoad()
会有:
yourButton.exclusiveTouch = true
。
//不是真的有必要,但你也可以添加:
self.view.multipleTouchEnabled = false
答案 8 :(得分:1)
用于在 Xamarin.iOS
中禁用全局多点触摸复制并粘贴以下代码:
[DllImport(ObjCRuntime.Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSend")]
internal extern static IntPtr IntPtr_objc_msgSend(IntPtr receiver, IntPtr selector, bool isExclusiveTouch);
static void SetExclusiveTouch(bool isExclusiveTouch)
{
var selector = new ObjCRuntime.Selector("setExclusiveTouch:");
IntPtr_objc_msgSend(UIView.Appearance.Handle, selector.Handle, isExclusiveTouch);
}
并在AppDelegate上进行设置:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
...
SetExclusiveTouch(true); // setting exlusive to true disables the multitouch
...
}
答案 9 :(得分:1)
非常简单,你可以在这种情况下使用ExclusiveTouch属性
[youBtn setExclusiveTouch:YES];
这是一个布尔值,指示接收器是否专门处理触摸事件。
将此属性设置为YES会导致接收方阻止将触摸事件传递到同一窗口中的其他视图。此属性的默认值为NO。
答案 10 :(得分:0)
在“Touch Down”事件中停用视图中的所有按钮,并在“Touch Up Inside”事件中启用它们。
例如
- (void) handleTouchDown {
for (UIButton *btn in views) {
btn.enable = NO;
}
}
- (void) handleTouchUpInside {
for (UIButton *btn in views) {
btn.enable = Yes;
}
------
------
}
答案 11 :(得分:0)
一个陷阱:
如果您使用的是isExclusiveTouch
,请注意,覆盖按钮上的point(inside:)
可能会造成干扰,从而使isExclusiveTouch
毫无用处。
(有时您需要覆盖point(inside:)
来处理“ 按钮在iPhone屏幕底部无响应”错误/功能不全(这是由于Apple在底部安装了滑动GestureRecognizers)屏幕,干扰按钮高亮显示。)
请参阅:UIButton fails to properly register touch in bottom region of iPhone screen
答案 12 :(得分:0)
在视图周围拖动对象时,我遇到了一些奇怪的情况,如果你同时触摸另一个对象,它会触发touchesBegan方法。我的解决方法是禁用父视图的用户交互,直到调用touchesEnded或touchesCancelled。
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
// whatever setup you need
self.view.userInteractionEnabled = false
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
// whatever setup you need
self.view.userInteractionEnabled = true
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
// whatever setup you need
self.view.userInteractionEnabled = true
}
答案 13 :(得分:0)
我通过这种方式决定了这个问题:
NSTimeInterval intervalButtonPressed;
- (IBAction)buttonPicturePressed:(id)sender{
if (([[NSDate date] timeIntervalSince1970] - intervalButtonPressed) > 0.1f) {
intervalButtonPressed = [[NSDate date] timeIntervalSince1970];
//your code for button
}
}
答案 14 :(得分:0)
如果要以编程方式禁用多点触控,或者如果您使用的是cocos2d(没有multipleTouchEnabled选项),则可以在ccTouches委托上使用以下代码:
- (BOOL)ccTouchesBegan:(NSSet *)touches
withEvent:(UIEvent *)event {
NSSet *multiTouch = [event allTouches];
if( [multiTouch count] > 1) {
return;
}
else {
//else your rest of the code
}
答案 15 :(得分:0)
我创建了UIView类扩展并添加了这两个函数。当我想禁用视图触摸时,我只需调用[view makeExclusiveTouch];
- (void) makeExclusiveTouchForViews:(NSArray*)views {
for (UIView * view in views) {
[view makeExclusiveTouch];
}
}
- (void) makeExclusiveTouch {
self.multipleTouchEnabled = NO;
self.exclusiveTouch = YES;
[self makeExclusiveTouchForViews:self.subviews];
}
答案 16 :(得分:0)
我刚才遇到了这个问题。
我们提出的解决方案只是从UIButton继承一个覆盖initWithCoder方法的新类,并在我们需要一次按下一个按钮的地方使用它(即无处不在):
@implementation ExclusiveButton
(id)initWithCoder: (NSCoder*)decoder
{
[self setExclusiveTouch:YES];
return [super initWithCoder:decoder]
}
@end
请注意,这仅适用于从nib文件加载的按钮。
答案 17 :(得分:0)
我的经验是,默认情况下,新项目甚至不允许多点触控,您必须将其打开。但我想这取决于你是如何开始的。您是否使用mutlitouch示例作为模板?
首先,你绝对确定多点触控?可以很快地按顺序生成单个触摸。多点触控更多地是关于你在表面上使用两个或多个手指时所做的事情。也许您只需单击一下,但如果几乎同时按下两个按钮,则无法正确处理。
答案 18 :(得分:-1)
只需将所有相关的UIView属性exclusiveTouch设置为false即可。