wake-up-neo.net

Wie kann man Multitouch deaktivieren?

Meine App verfügt über mehrere Schaltflächen, die verschiedene Ereignisse auslösen. Der Benutzer sollte NICHT mehrere Tasten gedrückt halten können. Wenn Sie jedoch mehrere Tasten gedrückt halten, stürzt die App ab.

Ich versuche also, Multi-Touch in meiner App zu deaktivieren.

Ich habe in allen xib-Dateien das Kontrollkästchen "Multiple Touch" deaktiviert, und soweit ich das herausfinden kann, steuern die Eigenschaften "multipleTouchEnabled" und "exclusiveTouch", ob die Ansicht Multitouch verwendet. So habe ich in meiner AnwendungDidFinishLaunching Folgendes eingefügt:

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

Und in jedem meiner View-Controller habe ich dies in viewDidLoad eingefügt

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

Still akzeptiert jedoch mehrere Berührungen. Ich könnte so etwas wie das Deaktivieren anderer Tasten tun, nachdem ich ein Touchdown-Ereignis erhalten habe, aber dies wäre ein hässlicher Hack. Sicher gibt es eine Möglichkeit, Multi-Touch richtig zu deaktivieren?

34
cannyboy

Wenn nur jeweils eine Schaltfläche auf Berührungen reagieren soll, müssen Sie exclusiveTouch für diese Schaltfläche und nicht für die übergeordnete Ansicht festlegen. Alternativ können Sie die anderen Schaltflächen deaktivieren, wenn für eine Schaltfläche das Ereignis "Touch Down" angezeigt wird.


Hier ist ein Beispiel für Letzteres, das in meinen Tests besser funktioniert hat. Das Setzen von exclusiveTouch für die Tasten funktionierte irgendwie, führte jedoch zu einigen interessanten Problemen, wenn Sie den Finger vom Rand einer Schaltfläche wegbewegten, anstatt nur darauf zu klicken.

Sie müssen Steckdosen in Ihrem Controller mit jeder Taste verbinden und die Ereignisse "Touch Down", "Touch Up Inside" und "Touch Up Outside" müssen mit den richtigen Methoden in Ihrem Controller verbunden sein.

#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
44
Mark Bessey
- (void)viewDidLoad {
    [super viewDidLoad];

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

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

Dieser Code ist getestet und funktioniert perfekt für mich. Es gibt keinen App-Absturz, wenn mehr als eine Taste gleichzeitig gedrückt wird.

5
Parth Mehta

Basierend auf der Antwort von neoevoke, die ich nur ein wenig verbessert habe, sodass auch die Kinder der Unteransichten überprüft werden, habe ich diese Funktion erstellt und meiner utils-Datei hinzugefügt: 

// 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];
        }
    }
}

Dann ein einfacher Aufruf an:

[Utils setExclusiveTouchToChildrenOf:self.view.subviews];

... wird es schaffen.

3
h4lc0n

Dies wird häufig von unseren Testern gemeldet. Ein Ansatz, den ich manchmal verwende, obwohl er bewusst verwendet werden sollte, ist das Erstellen einer Kategorie für UIView wie diese:

@implementation UIView (ExclusiveTouch)

- (BOOL)isExclusiveTouch
{
    return YES;
}
3
Krodak

Ihre App stürzt aus einem bestimmten Grund ab. Erkundigen Sie sich weiter, verwenden Sie den Debugger und sehen Sie, was falsch ist, anstatt den Fehler zu verbergen.

Bearbeiten:

OK, ok, ich muss zugeben, dass ich ein bisschen hart war. Sie müssen die Eigenschaft exclusiveTouch auf jeden Button setzen. Das ist alles. Die Eigenschaft multipleTouchEnabled ist irrelevant.

3
Nikolai Ruhe

So deaktivieren Sie Multitouch in Swift: 

Sie müssen zuerst einen Auslass für jede Taste haben und anschließend nur den exklusiven Touch auf "true" setzen. In diesem Fall hätte viewDidLoad():

yourButton.exclusiveTouch = true.

// nicht wirklich notwendig, aber Sie könnten auch hinzufügen:

self.view.multipleTouchEnabled = false

2
Alex Zanfir

Ziemlich einfach können Sie in diesem Fall die ExclusiveTouch-Eigenschaft verwenden

[youBtn setExclusiveTouch:YES];

Dies ist ein boolescher Wert, der angibt, ob der Empfänger ausschließlich Berührungsereignisse behandelt.

Wenn Sie diese Eigenschaft auf YES setzen, blockiert der Empfänger die Übermittlung von Berührungsereignissen an andere Ansichten im selben Fenster. Der Standardwert dieser Eigenschaft ist NO.

1
Aks

Wenn Sie Multi-Touch in der gesamten Anwendung deaktivieren möchten und keinen Code für jede Schaltfläche schreiben möchten, können Sie einfach Appearance der Taste verwenden. Schreiben Sie eine Zeile in didFinishLaunchingWithOptions.

UIButton.appearance().isExclusiveTouch = true

Das ist großartig!! UIA Auftritt

Sie können es sogar für eine beliebige UIView-Klasse verwenden, wenn Sie die Multi-Touch-Funktion für einige Tasten deaktivieren möchten. Erstellen Sie eine CustomClass-Schaltfläche und dann

CustomButton.appearance().isExclusiveTouch = true

Es gibt einen weiteren Vorteil, der Ihnen helfen kann. Falls Sie die Mehrfachberührung von Schaltflächen in einer bestimmten ViewController deaktivieren möchten

UIButton.appearance(whenContainedInInstancesOf: [ViewController2.self]).isExclusiveTouch = true
0
TheTiger

Ich habe die Erfahrung gemacht, dass ein neues Projekt standardmäßig nicht einmal Multitouch zulässt. Sie müssen es aktivieren. Aber ich denke, das hängt davon ab, wie Sie angefangen haben. Haben Sie ein mutlitouch-Beispiel als Vorlage verwendet?

Sind Sie sich absolut sicher, dass Multitouch eingeschaltet ist? Es ist möglich, einzelne Berührungen schnell nacheinander zu erzeugen. Bei Multitouch geht es mehr darum, was Sie mit zwei oder mehr Fingern machen, wenn sie auf der Oberfläche sind. Möglicherweise haben Sie eine einzelne Berührung, behandeln aber nicht richtig, was passiert, wenn zwei Tasten fast gleichzeitig gedrückt werden.

0
Nosredna

Ich hatte Probleme mit einigen seltsamen Fällen, wenn ich Objekte um eine Ansicht zog. Wenn Sie gleichzeitig ein anderes Objekt berührten, würde dies die touchesBegan-Methode auslösen. Mein Problem war, die Benutzerinteraktion für die übergeordnete Ansicht zu deaktivieren, bis touchEnded oder touchesCancelled aufgerufen wird. 

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
}
0
Gaston Martin

Zum Deaktivieren des globalen Multitouch in Xamarin.iOS

Kopieren Sie den folgenden Code und fügen Sie ihn ein:

[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);
}

Und setze es auf AppDelegate:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    ...
    SetExclusiveTouch(true); // setting exlusive to true disables the multitouch
    ...
}
0
mr5

Ich habe dieses Problem auf diese Weise entschieden:

NSTimeInterval intervalButtonPressed;

- (IBAction)buttonPicturePressed:(id)sender{ 

    if (([[NSDate date] timeIntervalSince1970] - intervalButtonPressed) > 0.1f) {
        intervalButtonPressed = [[NSDate date] timeIntervalSince1970];
        //your code for button
    }
}
0
Igor

Ich habe UIView Class Extension erstellt und diese beiden Funktionen hinzugefügt. und wenn ich view touch deaktivieren möchte, rufe ich einfach [view makeExclusiveTouch] an;

- (void) makeExclusiveTouchForViews:(NSArray*)views {
    for (UIView * view in views) {
        [view makeExclusiveTouch];
    }
}

- (void) makeExclusiveTouch {
    self.multipleTouchEnabled = NO;
    self.exclusiveTouch = YES;
    [self makeExclusiveTouchForViews:self.subviews];
}
0
kjhkjhkjh

Wenn Sie Multitouch programmgesteuert deaktivieren möchten oder cocos2d verwenden (keine Option multipleTouchEnabled), können Sie den folgenden Code für Ihren ccTouches-Delegaten verwenden:

- (BOOL)ccTouchesBegan:(NSSet *)touches
 withEvent:(UIEvent *)event {
       NSSet *multiTouch = [event allTouches];
       if( [multiTouch count] > 1) { 
            return; 
       }
       else {
           //else your rest of the code  
}
0
Jonny Ramos

Ich hatte gerade genau dieses Problem.

Die von uns entwickelte Lösung bestand einfach darin, eine neue Klasse von UIButton zu erben, die die Methode initWithCoder überschreibt, und die Stelle zu verwenden, an der wir einen Tastendruck (zu einem beliebigen Zeitpunkt) benötigen (dh überall):

@implementation ExclusiveButton

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

@end

Beachten Sie, dass dies nur mit Schaltflächen funktioniert, die aus Nib-Dateien geladen werden.

0
Andy Krouwel

Deaktivieren Sie alle Schaltflächen, die in "Touch Down" event angezeigt werden, und aktivieren Sie sie in "Touch Up Inside" event.

zum Beispiel

- (void) handleTouchDown {
    for (UIButton *btn in views) {
        btn.enable = NO;
    }
}

- (void) handleTouchUpInside {
    for (UIButton *btn in views) {
        btn.enable = Yes;
    }
    ------
    ------
}
0
Rajendra