Udostępnij za pośrednictwem


Zdarzenia i gesty dotykowe w środowisku Xamarin.iOS

Ważne jest, aby zrozumieć zdarzenia dotykowe i interfejsy API dotykowe w aplikacji systemu iOS, ponieważ są one kluczowe dla wszystkich fizycznych interakcji z urządzeniem. Wszystkie interakcje dotykowe obejmują UITouch obiekt. W tym artykule dowiesz się, jak używać UITouch klasy i jej interfejsów API do obsługi dotyku. Później rozszerzymy naszą wiedzę, aby dowiedzieć się, jak obsługiwać gesty.

Włączanie funkcji Touch

Kontrolki w UIKit systemie — te podklasy z interfejsu UIControl — są tak zależne od interakcji użytkownika, że mają gesty wbudowane w zestaw UIKit i dlatego nie jest konieczne włączenie funkcji Touch. Jest już włączona.

Jednak wiele widoków w programie UIKit nie ma domyślnie włączonego dotyku. Istnieją dwa sposoby włączania obsługi kontrolki. Pierwszym sposobem jest sprawdzenie pola wyboru Włączona interakcja użytkownika w okienku właściwości Projektant systemu iOS, jak pokazano na poniższym zrzucie ekranu:

Check the User Interaction Enabled checkbox in the Property Pad of the iOS Designer

Możemy również użyć kontrolera, aby ustawić UserInteractionEnabled właściwość na wartość true w UIView klasie. Jest to wymagane, jeśli interfejs użytkownika jest tworzony w kodzie.

Oto przykładowy wiersz kodu:

imgTouchMe.UserInteractionEnabled = true;

Zdarzenia dotykowe

Istnieją trzy fazy dotyku, które występują, gdy użytkownik dotyka ekranu, porusza palcem lub usuwa palec. Te metody są definiowane w UIResponderobiekcie , który jest klasą bazową dla interfejsu użytkownikaIView. System iOS zastąpi skojarzone metody w obiekcie UIView i UIViewController , aby obsługiwać dotyk:

  • TouchesBegan — Jest to wywoływane po pierwszym dotknięciu ekranu.
  • TouchesMoved – Jest to wywoływane, gdy lokalizacja dotyku zmienia się, gdy użytkownik przesuwa palce wokół ekranu.
  • TouchesEnded lub TouchesCancelledTouchesEnded jest wywoływany, gdy palce użytkownika są podnosine z ekranu. TouchesCancelled zostanie wywołana, jeśli system iOS anuluje dotyk — na przykład jeśli użytkownik przesuwa palcem z dala od przycisku, aby anulować naciśnięcie.

Zdarzenia dotykowe cyklicznie przechodzą przez stos elementów UIView, aby sprawdzić, czy zdarzenie dotykowe znajduje się w granicach obiektu widoku. Jest to często nazywane testowaniem trafień. Najpierw będą one wywoływane na najwyższym UIView poziomie lub UIViewController następnie będą wywoływane na UIViewUIViewControllers i poniżej w hierarchii widoków.

Obiekt UITouch zostanie utworzony za każdym razem, gdy użytkownik natknie się na ekranie. Obiekt UITouch zawiera dane dotyczące dotyku, takie jak kiedy doszło do dotyku, gdzie wystąpił, jeśli dotyk był machnięciem itp. Zdarzenia dotykowe są przekazywane właściwości touches — NSSet zawierające jeden lub więcej dotknięcia. Możemy użyć tej właściwości, aby uzyskać odwołanie do dotyku i określić odpowiedź aplikacji.

Klasy, które zastępują jedno z zdarzeń dotykowych, powinny najpierw wywołać implementację podstawową, a następnie pobrać UITouch obiekt skojarzony ze zdarzeniem. Aby uzyskać odwołanie do pierwszego dotknięcia, wywołaj właściwość i rzutuj AnyObject ją jako pokazaną UITouch w poniższym przykładzie:

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
    }
}

System iOS automatycznie rozpoznaje kolejne szybkie dotknięcia na ekranie i będzie zbierał je wszystkie jako jedno naciśnięcie w jednym UITouch obiekcie. Dzięki temu sprawdzanie podwójnego naciśnięcia jest tak proste, jak sprawdzanie TapCount właściwości, jak pokazano w poniższym kodzie:

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.
        }
    }
}

Multi-Touch

Funkcja Multi-touch nie jest domyślnie włączona w kontrolkach. Funkcję Multi-touch można włączyć w Projektant systemu iOS, jak pokazano na poniższym zrzucie ekranu:

Multi-touch enabled in the iOS Designer

Istnieje również możliwość programowego ustawiania wielodotyku, ustawiając MultipleTouchEnabled właściwość, jak pokazano w poniższym wierszu kodu:

imgTouchMe.MultipleTouchEnabled = true;

Aby określić, ile palców dotknął ekranu, użyj Count właściwości na UITouch właściwości :

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

Określanie lokalizacji dotykowej

Metoda UITouch.LocationInView zwraca obiekt CGPoint, który przechowuje współrzędne dotyku w danym widoku. Ponadto możemy sprawdzić, czy ta lokalizacja znajduje się w kontrolce, wywołując metodę Frame.Contains. Poniższy fragment kodu przedstawia przykład tego kodu:

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

Teraz, gdy mamy już wiedzę na temat zdarzeń dotykowych w systemie iOS, dowiedzmy się więcej o rozpoznawaniu gestów.

Rozpoznawanie gestów

Rozpoznawanie gestów może znacznie uprościć i zmniejszyć nakład pracy programistycznej w celu obsługi dotyku w aplikacji. Rozpoznawanie gestów systemu iOS agreguje serię zdarzeń dotykowych w jedno zdarzenie dotykowe.

Platforma Xamarin.iOS udostępnia klasę UIGestureRecognizer jako klasę bazową dla następujących wbudowanych funkcji rozpoznawania gestów:

  • UITapGestureRecognizer — dotyczy to co najmniej jednego naciśnięcia.
  • UIPinchGestureRecognizer – Szczypanie i rozkładanie palców.
  • UIPanGestureRecognizer — przesuwanie lub przeciąganie.
  • UISwipeGestureRecognizer — przesuwanie w dowolnym kierunku.
  • UIRotationGestureRecognizer — obracanie dwóch palców w ruchu wskazówek zegara lub w kierunku przeciwnym do ruchu wskazówek zegara.
  • UILongPressGestureRecognizer — naciśnij i przytrzymaj, czasami nazywany długim naciśnięciem lub długim kliknięciem.

Podstawowy wzorzec używania rozpoznawania gestów jest następujący:

  1. Utwórz wystąpienie rozpoznawania gestów — najpierw utwórz wystąpienie podklasy UIGestureRecognizer . Obiekt, który jest tworzone, zostanie skojarzony z widokiem i zostanie usunięty śmieci po usunięciu widoku. Nie jest konieczne utworzenie tego widoku jako zmiennej poziomu klasy.
  2. Skonfiguruj ustawienia gestów — następnym krokiem jest skonfigurowanie rozpoznawania gestów. Zapoznaj się z dokumentacją platformy Xamarin dotyczącą UIGestureRecognizer i jej podklasami, aby uzyskać listę właściwości, które można ustawić w celu kontrolowania zachowania UIGestureRecognizer wystąpienia.
  3. Skonfiguruj obiekt docelowy — ze względu na jego Objective-C dziedzictwo platforma Xamarin.iOS nie zgłasza zdarzeń, gdy aparat rozpoznawania gestów pasuje do gestu. UIGestureRecognizer ma metodę — AddTarget która może akceptować anonimowego delegata lub Objective-C selektora z kodem do wykonania, gdy rozpoznawanie gestów powoduje dopasowanie.
  4. Włącz rozpoznawanie gestów — podobnie jak w przypadku zdarzeń dotykowych gesty są rozpoznawane tylko w przypadku włączenia interakcji dotykowych.
  5. Dodawanie rozpoznawania gestów do widoku — ostatnim krokiem jest dodanie gestu do widoku przez wywołanie View.AddGestureRecognizer metody i przekazanie go obiektu rozpoznawania gestów.

Aby uzyskać więcej informacji na temat implementowania ich w kodzie, zapoznaj się z przykładami rozpoznawania gestów .

Po wywołaniu obiektu docelowego gestu zostanie przekazane odwołanie do gestu, który wystąpił. Dzięki temu obiekt docelowy gestu uzyskuje informacje o gestie, który wystąpił. Zakres dostępnych informacji zależy od typu używanego rozpoznawania gestów. Aby uzyskać informacje o danych dostępnych dla każdej UIGestureRecognizer podklasy, zobacz dokumentację platformy Xamarin.

Należy pamiętać, że po dodaniu rozpoznawania gestów do widoku widok (i wszystkich poniższych widoków) nie będą odbierać żadnych zdarzeń dotykowych. Aby zezwolić na zdarzenia dotykowe jednocześnie z gestami, CancelsTouchesInView właściwość musi być ustawiona na wartość false, jak pokazano w poniższym kodzie:

_tapGesture.Recognizer.CancelsTouchesInView = false;

Każda z nich UIGestureRecognizer ma właściwość State, która zawiera ważne informacje o stanie rozpoznawania gestów. Za każdym razem, gdy wartość tej właściwości ulegnie zmianie, system iOS wywoła metodę subskrybowania, dając jej aktualizację. Jeśli niestandardowy aparat rozpoznawania gestów nigdy nie aktualizuje właściwości State, subskrybent nigdy nie jest wywoływany, co sprawia, że rozpoznawanie gestów jest bezużyteczne.

Gesty można podsumować jako jeden z dwóch typów:

  1. Dyskretne — te gesty uruchamiają tylko po raz pierwszy, gdy są rozpoznawane.
  2. Ciągły — te gesty nadal są uruchamiane tak długo, jak są rozpoznawane.

Rozpoznawanie gestów istnieje w jednym z następujących stanów:

  • Możliwe — jest to początkowy stan wszystkich funkcji rozpoznawania gestów. Jest to wartość domyślna właściwości State.
  • Rozpoczęto — gdy po raz pierwszy rozpoznano gest ciągły, stan jest ustawiony na Rozpoczęto. Dzięki temu subskrybuj można rozróżniać czas uruchamiania rozpoznawania gestów i jego zmiany.
  • Zmieniono — po rozpoczęciu gestu ciągłego, ale nie zakończono, stan zostanie ustawiony na Zmieniono za każdym razem, gdy dotyk porusza się lub zmienia, o ile nadal mieści się w oczekiwanych parametrach gestu.
  • Anulowano — ten stan zostanie ustawiony, jeśli rozpoznający przeszedł z Rozpoczęto na Zmieniono, a następnie dotknięcia zmieniły się w taki sposób, aby nie pasowały już do wzorca gestu.
  • Rozpoznane — stan zostanie ustawiony, gdy aparat rozpoznawania gestów pasuje do zestawu akcentów i poinformuje subskrybenta o zakończeniu gestu.
  • Ended — jest to alias stanu Rozpoznano.
  • Niepowodzenie — gdy aparat rozpoznawania gestów nie może już dopasować dotyku, na który nasłuchuje, stan zmieni się na Niepowodzenie.

Środowisko Xamarin.iOS reprezentuje te wartości w wyliczenie UIGestureRecognizerState .

Praca z wieloma gestami

Domyślnie system iOS nie zezwala na jednoczesne uruchamianie domyślnych gestów. Zamiast tego każdy aparat rozpoznawania gestów będzie otrzymywać zdarzenia dotykowe w kolejności niedeterministycznej. Poniższy fragment kodu ilustrował sposób jednoczesnego uruchamiania rozpoznawania gestów:

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

Można również wyłączyć gest w systemie iOS. Istnieją dwie właściwości delegata, które umożliwiają rozpoznawanie gestów do badania stanu aplikacji i bieżących zdarzeń dotykowych, aby podejmować decyzje dotyczące sposobu i tego, czy gest powinien zostać rozpoznany. Dwa zdarzenia to:

  1. ShouldReceiveTouch — ten delegat jest wywoływany bezpośrednio przed przekazaniem zdarzenia dotykowego przez rozpoznawanie gestów i daje możliwość sprawdzenia dotyku i podjęcia decyzji, które dotknięcia będą obsługiwane przez rozpoznawanie gestów.
  2. ShouldBegin — jest to wywoływane, gdy rozpoznawanie próbuje zmienić stan z Możliwe na inny stan. Zwracanie wartości false wymusi zmianę stanu rozpoznawania gestu na Niepowodzenie.

Te metody można zastąpić za pomocą silnie typizowanego UIGestureRecognizerDelegate, słabego delegata lub powiązania za pomocą składni procedury obsługi zdarzeń, jak pokazano w poniższym fragmencie kodu:

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

Na koniec istnieje możliwość kolejkowania rozpoznawania gestów tak, aby zakończyła się powodzeniem tylko wtedy, gdy inny aparat rozpoznawania gestów ulegnie awarii. Na przykład rozpoznawanie gestu pojedynczego naciśnięcia powinno zakończyć się powodzeniem tylko wtedy, gdy rozpoznawanie gestów dwukrotnego naciśnięcia zakończy się niepowodzeniem. Poniższy fragment kodu zawiera przykład tego kodu:

singleTapGesture.RequireGestureRecognizerToFail(doubleTapGesture);

Tworzenie gestu niestandardowego

Mimo że system iOS udostępnia niektóre domyślne funkcje rozpoznawania gestów, w niektórych przypadkach może być konieczne utworzenie niestandardowych funkcji rozpoznawania gestów. Tworzenie niestandardowego rozpoznawania gestów obejmuje następujące kroki:

  1. Podklasa UIGestureRecognizer .
  2. Zastąpij odpowiednie metody zdarzeń dotyku.
  3. Stan rozpoznawania bąbelka w górę za pośrednictwem właściwości State klasy bazowej.

Praktyczny przykład zostanie omówiony w przewodniku Using Touch w systemie iOS .