41

我的应用程序有几个触发不同事件的按钮。用户不应该能够按住几个按钮。无论如何,按住几个按钮会使应用程序崩溃。

所以,我试图在我的应用程序中禁用多点触控。

我已经在所有 xib 文件中取消选中“多点触控”,据我所知,“multipleTouchEnabled”和“exclusiveTouch”属性控制视图是否使用多点触控。所以在我的 applicationDidFinishLaunching 我放了这个:

self.mainViewController.view.multipleTouchEnabled = NO;
self.mainViewController.view.exclusiveTouch = YES;

在我的每个视图控制器中,我都把它放在了 viewDidLoad

self.view.multipleTouchEnabled = NO;
self.view.exclusiveTouch = YES;

但是,它仍然接受多次触摸。在发生触地事件后,我可以执行诸如禁用其他按钮之类的操作,但这将是一个丑陋的黑客行为。当然有一种方法可以正确禁用多点触控?

4

19 回答 19

48

如果您希望一次只有一个按钮响应触摸,则需要为该按钮设置 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
于 2009-07-03T17:40:44.070 回答
21
- (void)viewDidLoad {
    [super viewDidLoad];

    for(UIView* v in self.view.subviews)
    {
        if([v isKindOfClass:[UIButton class]])
        {
            UIButton* btn = (UIButton*)v;
            [btn setExclusiveTouch:YES];
        }
    }
}
于 2011-06-03T08:01:35.980 回答
6
- (void)viewDidLoad {
    [super viewDidLoad];

    for(UIView* v in self.view.subviews)
    {
        if([v isKindOfClass:[UIButton class]])
        {
            UIButton* btn = (UIButton*)v;
            [btn setExclusiveTouch:YES];
        }
    }
}

这段代码已经过测试并且对我来说完美运行。一次按下多个按钮时不会出现应用程序崩溃。

于 2013-11-23T06:10:56.287 回答
5

您的应用程序崩溃是有原因的。进一步调查,使用调试器,看看出了什么问题,而不是试图隐藏错误。

编辑:

好吧,好吧,我不得不承认我有点苛刻。您必须在每个按钮上设置 ExclusiveTouch 属性。就这样。multipleTouchEnabled 属性无关紧要。

于 2009-07-03T16:33:27.787 回答
4

要在 SWIFT 中禁用多点触控:

您首先需要每个按钮都有一个插座,然后只需将独占触摸设置为 true。因此,您viewDidLoad()将拥有:

yourButton.exclusiveTouch = true.

// 不是很必要,但您也可以添加:

self.view.multipleTouchEnabled = false

于 2015-11-25T08:47:15.057 回答
4

如果您想在整个应用程序中禁用多点触控并且不想为每个按钮编写代码,那么您可以简单地使用Appearance按钮。写在下面的行中didFinishLaunchingWithOptions

UIButton.appearance().isExclusiveTouch = true

那太棒了!!UI外观

您甚至可以将它用于任何UIView课程,因此如果您想为几个按钮禁用多点触控。制作一个CustomClass按钮,然后

CustomButton.appearance().isExclusiveTouch = true

还有一个优势可以帮助您。如果您想在特定的情况下禁用多点触控按钮ViewController

UIButton.appearance(whenContainedInInstancesOf: [ViewController2.self]).isExclusiveTouch = true
于 2018-03-15T12:40:38.713 回答
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];

......会成功的。

于 2013-12-20T08:59:36.573 回答
3

这是我们的测试人员经常报告的问题。尽管应该有意识地使用它,但我有时使用的一种方法是为 创建类别UIView,如下所示:

@implementation UIView (ExclusiveTouch)

- (BOOL)isExclusiveTouch
{
    return YES;
}
于 2014-11-25T10:48:08.127 回答
2

在这种情况下,您可以使用 ExclusiveTouch 属性非常简单

[youBtn setExclusiveTouch:YES];

这是一个布尔值,指示接收器是否专门处理触摸事件。

将此属性设置为 YES 会导致接收器阻止将触摸事件传递到同一窗口中的其他视图。此属性的默认值为 NO。

于 2016-08-25T18:34:35.413 回答
2

用于在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
    ...
}
于 2018-09-13T05:14:36.013 回答
0

我的经验是,默认情况下,一个新项目甚至不允许多点触控,你必须打开它。但我想这取决于你是如何开始的。您是否使用多点触控示例作为模板?

首先,你确定多点触控是开启的吗?可以很快地按顺序生成单次触摸。多点触控更多的是关于你用两个或更多手指在表面上所做的事情。也许您只进行了一次触摸,但没有正确处理如果几乎同时按下两个按钮会发生什么。

于 2009-07-03T16:47:30.393 回答
0

我刚刚遇到了这个问题。

我们想出的解决方案是简单地从 UIButton 继承一个新类,该类覆盖 initWithCoder 方法,并在我们需要一次按一个按钮的地方使用它(即无处不在):

@implementation ExclusiveButton

(id)initWithCoder: (NSCoder*)decoder 
{ 
   [self setExclusiveTouch:YES]; 
   return [super initWithCoder:decoder]
}

@end

请注意,这只适用于从 nib 文件加载的按钮。

于 2010-05-24T12:04:44.773 回答
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];
}
于 2013-06-01T08:33:32.423 回答
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  
}
于 2013-06-03T16:00:51.647 回答
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;
    }
    ------
    ------
}
于 2014-01-11T11:15:45.657 回答
0

我通过这种方式决定了这个问题:

NSTimeInterval intervalButtonPressed;

- (IBAction)buttonPicturePressed:(id)sender{ 

    if (([[NSDate date] timeIntervalSince1970] - intervalButtonPressed) > 0.1f) {
        intervalButtonPressed = [[NSDate date] timeIntervalSince1970];
        //your code for button
    }
}
于 2014-10-09T11:00:07.730 回答
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
}
于 2016-01-27T17:07:31.697 回答
0

一个问题:

如果您正在使用isExclusiveTouch,请注意覆盖point(inside:)按钮可能会造成干扰,从而导致isExclusiveTouch无效。

(有时您需要覆盖point(inside:)以处理“按钮在 iPhone 屏幕底部无响应”错误/错误功能(这是由 Apple 在屏幕底部安装滑动 GestureRecognizers 造成的,干扰按钮突出显示。)

请参阅:UIButton 无法在 iPhone 屏幕的底部区域正确注册触摸

于 2020-08-13T02:34:55.840 回答
-1

只需将所有相关的 UIView 的属性 ExclusiveTouch 设置为 false 即可。

于 2014-12-28T16:54:37.593 回答