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:
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 UIResponder
obiekcie , 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
lubTouchesCancelled
—TouchesEnded
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 UIView
UIViewControllers
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:
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:
- 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. - 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 zachowaniaUIGestureRecognizer
wystąpienia. - 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. - Włącz rozpoznawanie gestów — podobnie jak w przypadku zdarzeń dotykowych gesty są rozpoznawane tylko w przypadku włączenia interakcji dotykowych.
- 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:
- Dyskretne — te gesty uruchamiają tylko po raz pierwszy, gdy są rozpoznawane.
- 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:
- 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.
- 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:
- Podklasa
UIGestureRecognizer
. - Zastąpij odpowiednie metody zdarzeń dotyku.
- 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 .