Freigeben über


Touchereignisse und Gesten in Xamarin.iOS

Es ist wichtig, die Touchereignisse und Touch-APIs in einer iOS-Anwendung zu verstehen, da sie für alle physischen Interaktionen mit dem Gerät von zentraler Bedeutung sind. Alle Touchinteraktionen beziehen sich auf ein UITouch Objekt. In diesem Artikel erfahren Sie, wie Sie die -Klasse und ihre UITouch APIs verwenden, um Toucheingaben zu unterstützen. Später werden wir unser Wissen erweitern, um zu lernen, wie Gesten unterstützt werden können.

Aktivieren der Toucheingabe

Steuerelemente in UIKit – die unterklassiert von UIControl – sind so von der Benutzerinteraktion abhängig, dass sie Gesten in UIKit integriert haben, und daher ist es nicht erforderlich, Touch zu aktivieren. Es ist bereits aktiviert.

Bei vielen Ansichten in UIKit ist die Toucheingabe jedoch nicht standardmäßig aktiviert. Es gibt zwei Möglichkeiten, die Toucheingabe für ein Steuerelement zu aktivieren. Die erste Möglichkeit besteht darin, das Kontrollkästchen Benutzerinteraktion aktiviert im Eigenschaftenpad der iOS-Designer zu aktivieren, wie im folgenden Screenshot gezeigt:

Aktivieren Sie das Kontrollkästchen Benutzerinteraktion aktiviert im Eigenschaftenpad des iOS-Designer

Wir können auch einen Controller verwenden, um die UserInteractionEnabled Eigenschaft für eine UIView Klasse auf true festzulegen. Dies ist erforderlich, wenn die Benutzeroberfläche im Code erstellt wird.

Die folgende Codezeile ist ein Beispiel:

imgTouchMe.UserInteractionEnabled = true;

Berührungsereignisse

Es gibt drei Phasen der Berührung, die auftreten, wenn der Benutzer den Bildschirm berührt, seinen Finger bewegt oder seinen Finger entfernt. Diese Methoden werden in UIResponderdefiniert, wobei es sich um die Basisklasse für UIView handelt. iOS überschreibt die zugeordneten Methoden für und UIView zum Verarbeiten der UIViewController Toucheingabe:

  • TouchesBegan – Dies wird aufgerufen, wenn der Bildschirm zum ersten Mal berührt wird.
  • TouchesMoved – Dies wird aufgerufen, wenn sich die Position der Toucheingabe ändert, wenn der Benutzer seine Finger um den Bildschirm gleitet.
  • TouchesEnded oder TouchesCancelledTouchesEnded wird aufgerufen, wenn die Finger des Benutzers vom Bildschirm gehoben werden. TouchesCancelled wird aufgerufen, wenn iOS die Berührung abbricht, z. B. wenn ein Benutzer seinen Finger von einer Schaltfläche wegschiebt, um eine Drucktaste abzubrechen.

Touchereignisse wandern rekursiv durch den Stapel von UIViews, um zu überprüfen, ob sich das Touchereignis innerhalb der Grenzen eines Ansichtsobjekts befindet. Dies wird häufig als Treffertest bezeichnet. Sie werden zuerst am obersten UIView oder UIViewController aufgerufen und dann in der UIView Ansichtshierarchie auf und UIViewControllers darunter aufgerufen.

Jedes UITouch Mal, wenn der Benutzer den Bildschirm berührt, wird ein Objekt erstellt. Das UITouch Objekt enthält Daten zur Berührung, z. B. wann die Berührung stattgefunden hat, wo sie aufgetreten ist, ob die Berührung ein Wischvorgang war usw. Die Touchereignisse erhalten eine touches-Eigenschaft – eine NSSet , die mindestens eine Toucheingabe enthält. Wir können diese Eigenschaft verwenden, um einen Verweis auf eine Toucheingabe abzurufen und die Antwort der Anwendung zu bestimmen.

Klassen, die eines der Touchereignisse überschreiben, sollten zuerst die Basisimplementierung aufrufen und dann das UITouch dem Ereignis zugeordnete Objekt abrufen. Um einen Verweis auf die erste Berührung zu erhalten, rufen Sie die AnyObject -Eigenschaft auf, und wandeln Sie sie wie im folgenden Beispiel gezeigt als eine um UITouch :

public override void TouchesBegan (NSSet touches, UIEvent evt)
{
    base.TouchesBegan (touches, evt);
    UITouch touch = touches.AnyObject as UITouch;
    if (touch != null)
    {
        //code here to handle touch
    }
}

iOS erkennt automatisch aufeinander folgende schnelle Berührungen auf dem Bildschirm und sammelt sie alle als ein Tippen in einem einzelnen UITouch Objekt. Dies macht die Suche nach einem Doppeltippen so einfach wie die Überprüfung der TapCount Eigenschaft, wie im folgenden Code veranschaulicht:

public override void TouchesBegan (NSSet touches, UIEvent evt)
{
    base.TouchesBegan (touches, evt);
    UITouch touch = touches.AnyObject as UITouch;
    if (touch != null)
    {
        if (touch.TapCount == 2)
        {
            // do something with the double touch.
        }
    }
}

Multitouch

Multitouch ist für Steuerelemente standardmäßig nicht aktiviert. Multitouch kann im iOS-Designer aktiviert werden, wie im folgenden Screenshot veranschaulicht:

Multitouch aktiviert im iOS-Designer

Es ist auch möglich, multitouch programmgesteuert festzulegen, indem Sie die MultipleTouchEnabled -Eigenschaft wie in der folgenden Codezeile gezeigt festlegen:

imgTouchMe.MultipleTouchEnabled = true;

Verwenden Sie Count die -Eigenschaft für die -Eigenschaft, um zu bestimmen, wie viele Finger den UITouch Bildschirm berührt haben:

public override void TouchesBegan (NSSet touches, UIEvent evt)
{
    base.TouchesBegan (touches, evt);
    lblNumberOfFingers.Text = "Number of fingers: " + touches.Count.ToString();
}

Bestimmen des Touchstandorts

Die -Methode UITouch.LocationInView gibt ein CGPoint-Objekt zurück, das die Koordinaten der Berührung in einer bestimmten Ansicht enthält. Darüber hinaus können wir testen, ob sich dieser Speicherort innerhalb eines Steuerelements befindet, indem wir die -Methode Frame.Containsaufrufen. Der folgende Codeausschnitt zeigt ein Beispiel dafür:

if (this.imgTouchMe.Frame.Contains (touch.LocationInView (this.View)))
{
    // the touch event happened inside the UIView imgTouchMe.
}

Nachdem wir uns nun mit den Touchereignissen in iOS auskennen, lernen wir nun die Gestenerkennung kennen.

Gestenerkennung

Gestenerkennungen können den Programmieraufwand zur Unterstützung von Toucheingaben in einer Anwendung erheblich vereinfachen und reduzieren. iOS-Gestenerkennungen aggregieren eine Reihe von Touchereignissen in einem einzelnen Touchereignis.

Xamarin.iOS stellt die -Klasse UIGestureRecognizer als Basisklasse für die folgenden integrierten Gestenerkennungen bereit:

  • UITapGestureRecognizer : Dies ist für mindestens einen Tippen vorgesehen.
  • UIPinchGestureRecognizer – Finger anheften und verteilen.
  • UIPanGestureRecognizer – Verschieben oder Ziehen.
  • UISwipeGestureRecognizer – Wischen in jede Richtung.
  • UIRotationGestureRecognizer – Drehen von zwei Fingern in einer Bewegung im Uhrzeigersinn oder gegen den Uhrzeigersinn.
  • UILongPressGestureRecognizer : Drücken Und halten Sie sie gedrückt, manchmal auch als Long-Press oder Long-Click bezeichnet.

Das grundlegende Muster für die Verwendung einer Gestenerkennung sieht wie folgt aus:

  1. Instanziieren der Gestenerkennung : Instanziieren Sie zunächst eine UIGestureRecognizer Unterklasse. Das Objekt, das instanziiert wird, wird durch eine Ansicht zugeordnet und wird beim Löschen der Ansicht mit Müll erfasst. Es ist nicht erforderlich, diese Ansicht als Variable auf Klassenebene zu erstellen.
  2. Konfigurieren von Gesteneinstellungen : Der nächste Schritt besteht darin, die Gestenerkennung zu konfigurieren. Eine Liste von Eigenschaften, die festgelegt werden können, um das Verhalten eines UIGestureRecognizer instance zu steuern, finden Sie in der Dokumentation UIGestureRecognizer zu und den zugehörigen Unterklassen von Xamarin.
  3. Konfigurieren des Ziels : Aufgrund des Objective-C Erbes löst Xamarin.iOS keine Ereignisse aus, wenn eine Gestenerkennung mit einer Geste übereinstimmt. UIGestureRecognizer verfügt über eine -Methode – AddTarget , die einen anonymen Delegat oder einen Objective-C Selektor mit dem Code akzeptieren kann, der ausgeführt werden soll, wenn die Gestenerkennung eine Übereinstimmung macht.
  4. Aktivieren der Gestenerkennung : Wie bei Touchereignissen werden Gesten nur erkannt, wenn Touchinteraktionen aktiviert sind.
  5. Hinzufügen der Gestenerkennung zur Ansicht : Der letzte Schritt besteht darin, die Geste einer Ansicht hinzuzufügen, indem Sie aufrufen View.AddGestureRecognizer und ihr ein Gestenerkennungsobjekt übergeben.

Weitere Informationen zur Implementierung in Code finden Sie in den Gestenerkennungsbeispielen .

Wenn das Ziel der Geste aufgerufen wird, wird ein Verweis auf die Geste übergeben, die aufgetreten ist. Dadurch kann das Gestenziel Informationen über die aufgetretene Geste abrufen. Der Umfang der verfügbaren Informationen hängt vom Typ der verwendeten Gestenerkennung ab. Informationen zu den verfügbaren Daten für die einzelnen UIGestureRecognizer Unterklassen finden Sie in der Xamarin-Dokumentation.

Es ist wichtig zu beachten, dass die Ansicht (und alle darunter liegenden Ansichten) keine Berührungsereignisse empfängt, sobald eine Gestenerkennung zu einer Ansicht hinzugefügt wurde. Damit Touchereignisse gleichzeitig mit Gesten zugelassen werden können, muss die CancelsTouchesInView Eigenschaft auf false festgelegt werden, wie im folgenden Code veranschaulicht:

_tapGesture.Recognizer.CancelsTouchesInView = false;

Jede UIGestureRecognizer verfügt über eine State-Eigenschaft, die wichtige Informationen über die status der Gestenerkennung bereitstellt. Jedes Mal, wenn sich der Wert dieser Eigenschaft ändert, ruft iOS die abonnierende Methode auf, um sie zu aktualisieren. Wenn eine benutzerdefinierte Gestenerkennung die State-Eigenschaft nie aktualisiert, wird der Abonnent nie aufgerufen, sodass die Gestenerkennung nutzlos ist.

Gesten können als eine von zwei Typen zusammengefasst werden:

  1. Diskret : Diese Gesten werden nur ausgelöst, wenn sie zum ersten Mal erkannt werden.
  2. Kontinuierlich : Diese Gesten werden weiterhin ausgelöst, solange sie erkannt werden.

Gestenerkennungen sind in einem der folgenden Zustände vorhanden:

  • Möglich : Dies ist der Anfangszustand aller Gestenerkennungserkennungen. Dies ist der Standardwert der State-Eigenschaft.
  • Begonnen : Wenn eine fortlaufende Geste zuerst erkannt wird, wird der Status auf Begonnen festgelegt. Dadurch können Abonnenten unterscheiden, wann die Gestenerkennung beginnt und wann sie geändert wird.
  • Geändert : Nachdem eine fortlaufende Geste begonnen, aber noch nicht abgeschlossen wurde, wird der Zustand jedes Mal auf Geändert festgelegt, wenn sich eine Berührung bewegt oder sich ändert, solange sie sich noch innerhalb der erwarteten Parameter der Geste befindet.
  • Abgebrochen : Dieser Zustand wird festgelegt, wenn die Erkennung von Begonnen auf Geändert wechselt, und dann haben sich die Berührungen so geändert, dass sie nicht mehr dem Muster der Geste entsprechen.
  • Erkannt : Der Zustand wird festgelegt, wenn die Gestenerkennung mit einer Reihe von Berührungen übereinstimmt, und informiert den Abonnenten darüber, dass die Geste beendet ist.
  • Beendet : Dies ist ein Alias für den Status Erkannt.
  • Fehler: Wenn die Gestenerkennung nicht mehr mit den Berührungen übereinstimmen kann, auf die er lauscht, wird der Zustand in Fehler geändert.

Xamarin.iOS stellt diese Werte in der UIGestureRecognizerState Enumeration dar.

Arbeiten mit mehreren Gesten

Standardmäßig lässt iOS die gleichzeitige Ausführung von Standardgesten nicht zu. Stattdessen empfängt jede Gestenerkennung Touchereignisse in einer nicht deterministischen Reihenfolge. Der folgende Codeausschnitt veranschaulicht, wie eine Gestenerkennung gleichzeitig ausgeführt wird:

gesture.ShouldRecognizeSimultaneously += (UIGestureRecognizer r) => { return true; };

Es ist auch möglich, eine Geste in iOS zu deaktivieren. Es gibt zwei Delegateigenschaften, mit denen eine Gestenerkennung den Zustand einer Anwendung und die aktuellen Touchereignisse untersuchen kann, um Entscheidungen darüber zu treffen, wie und ob eine Geste erkannt werden soll. Die beiden Ereignisse sind:

  1. ShouldReceiveTouch : Dieser Delegat wird direkt aufgerufen, bevor die Gestenerkennung ein Touchereignis übergeben wird, und bietet die Möglichkeit, die Berührungen zu untersuchen und zu entscheiden, welche Berührungen von der Gestenerkennung behandelt werden.
  2. ShouldBegin : Dies wird aufgerufen, wenn eine Erkennung versucht, den Zustand von Möglich in einen anderen Zustand zu ändern. Wenn Sie false zurückgeben, wird der Zustand der Gestenerkennung in Fehler geändert.

Sie können diese Methoden mit einem stark typisierten UIGestureRecognizerDelegate, einem schwachen Delegat oder einer Bindung über die Ereignishandlersyntax überschreiben, wie im folgenden Codeausschnitt veranschaulicht:

gesture.ShouldReceiveTouch += (UIGestureRecognizer r, UITouch t) => { return true; };

Schließlich ist es möglich, eine Gestenerkennung in die Warteschlange zu stellen, sodass sie nur erfolgreich ist, wenn eine andere Gestenerkennung fehlschlägt. Beispielsweise sollte eine Gestenerkennung mit einmaligem Tippen nur erfolgreich sein, wenn bei einer Doppeltippgestenerkennung ein Fehler auftritt. Der folgende Codeausschnitt enthält ein Beispiel dafür:

singleTapGesture.RequireGestureRecognizerToFail(doubleTapGesture);

Erstellen einer benutzerdefinierten Geste

Obwohl iOS einige Standardmäßige Gestenerkennungen bereitstellt, kann es in bestimmten Fällen erforderlich sein, benutzerdefinierte Gestenerkennungen zu erstellen. Das Erstellen einer benutzerdefinierten Gestenerkennung umfasst die folgenden Schritte:

  1. Unterklasse UIGestureRecognizer .
  2. Überschreiben Sie die entsprechenden Touchereignismethoden.
  3. Die Erkennung status über die State-Eigenschaft der Basisklasse aufgeblasen.

Ein praktisches Beispiel hierfür finden Sie in der exemplarischen Vorgehensweise Verwenden von Touch in iOS .