Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento názorný postup ukazuje, jak napsat kód, který reaguje na různé druhy dotykových událostí. Každý příklad je obsažený na samostatné obrazovce:
- Dotykové ukázky – jak reagovat na dotykové události.
- Ukázky rozpoznávání gest – jak používat integrované rozpoznávání gest.
- Ukázka vlastního rozpoznávání gest – jak vytvořit vlastní rozpoznávání gest.
Každá část obsahuje pokyny k napsání kódu úplně od začátku.
Podle následujících pokynů přidejte kód do scénáře a seznamte se s různými typy dotykových událostí dostupných v iOSu.
Ukázky dotykového ovládání
V této ukázce si ukážeme některá dotyková rozhraní API. Pokud chcete přidat kód potřebný k implementaci dotykových událostí, postupujte takto:
Otevřete Touch_Start projektu. Nejprve spusťte projekt, abyste měli jistotu, že je všechno v pořádku, a klepněte na tlačítko Vzorky dotykového ovládání. Měla by se zobrazit obrazovka podobná následující (i když žádná z tlačítek nebude fungovat):
Upravte soubor TouchViewController.cs a přidejte do třídy
TouchViewControllernásledující dvě proměnné instance:#region Private Variables private bool imageHighlighted = false; private bool touchStartedInside; #endregionImplementujte metodu
TouchesBegan, jak je znázorněno v následujícím kódu:public override void TouchesBegan(NSSet touches, UIEvent evt) { base.TouchesBegan(touches, evt); // If Multitouch is enabled, report the number of fingers down TouchStatus.Text = string.Format ("Number of fingers {0}", touches.Count); // Get the current touch UITouch touch = touches.AnyObject as UITouch; if (touch != null) { // Check to see if any of the images have been touched if (TouchImage.Frame.Contains(touch.LocationInView(TouchView))) { // Fist image touched TouchImage.Image = UIImage.FromBundle("TouchMe_Touched.png"); TouchStatus.Text = "Touches Began"; } else if (touch.TapCount == 2 && DoubleTouchImage.Frame.Contains(touch.LocationInView(TouchView))) { // Second image double-tapped, toggle bitmap if (imageHighlighted) { DoubleTouchImage.Image = UIImage.FromBundle("DoubleTapMe.png"); TouchStatus.Text = "Double-Tapped Off"; } else { DoubleTouchImage.Image = UIImage.FromBundle("DoubleTapMe_Highlighted.png"); TouchStatus.Text = "Double-Tapped On"; } imageHighlighted = !imageHighlighted; } else if (DragImage.Frame.Contains(touch.LocationInView(View))) { // Third image touched, prepare to drag touchStartedInside = true; } } }Tato metoda funguje tak, že vyhledá
UITouchobjekt a pokud existuje, provede nějakou akci na základě místa, kde došlo k dotyku:- Uvnitř TouchImage – zobrazí text
Touches Beganv popisku a změní obrázek. - Uvnitř DoubleTouchImage – změňte obrázek zobrazený, pokud gesto bylo poklepání.
- Uvnitř DragImage – nastavte příznak označující, že se dotykové ovládání spustilo. Tato metoda
TouchesMovedpoužije tento příznak k určení, jestliDragImagese má pohybovat po obrazovce nebo ne, jak je vidět v dalším kroku.
Výše uvedený kód se zabývá pouze individuálními dotyky, neexistuje žádné chování, pokud uživatel posouvá prst na obrazovce. Pokud chcete reagovat na přesun, implementujte
TouchesMovedho, jak je znázorněno v následujícím kódu:public override void TouchesMoved(NSSet touches, UIEvent evt) { base.TouchesMoved(touches, evt); // get the touch UITouch touch = touches.AnyObject as UITouch; if (touch != null) { //==== IMAGE TOUCH if (TouchImage.Frame.Contains(touch.LocationInView(TouchView))) { TouchStatus.Text = "Touches Moved"; } //==== IMAGE DRAG // check to see if the touch started in the drag me image if (touchStartedInside) { // move the shape float offsetX = touch.PreviousLocationInView(View).X - touch.LocationInView(View).X; float offsetY = touch.PreviousLocationInView(View).Y - touch.LocationInView(View).Y; DragImage.Frame = new RectangleF(new PointF(DragImage.Frame.X - offsetX, DragImage.Frame.Y - offsetY), DragImage.Frame.Size); } } }Tato metoda získá
UITouchobjekt a pak zkontroluje, kde došlo k dotyku. Pokud k dotykovému ovládání došloTouchImage, zobrazí se na obrazovce text Touches Moved (Přesunuto).Pokud
touchStartedInsideje pravda, pak víme, že uživatel má prst na ruceDragImagea pohybuje se kolem. Kód se přesuneDragImage, když uživatel posouvají prst po obrazovce.- Uvnitř TouchImage – zobrazí text
Musíme zpracovat případ, kdy uživatel zvedne prst z obrazovky nebo iOS zruší dotykovou událost. V tomto případě budeme implementovat
TouchesEndedaTouchesCancelledjak je znázorněno níže:public override void TouchesCancelled(NSSet touches, UIEvent evt) { base.TouchesCancelled(touches, evt); // reset our tracking flags touchStartedInside = false; TouchImage.Image = UIImage.FromBundle("TouchMe.png"); TouchStatus.Text = ""; } public override void TouchesEnded(NSSet touches, UIEvent evt) { base.TouchesEnded(touches, evt); // get the touch UITouch touch = touches.AnyObject as UITouch; if (touch != null) { //==== IMAGE TOUCH if (TouchImage.Frame.Contains(touch.LocationInView(TouchView))) { TouchImage.Image = UIImage.FromBundle("TouchMe.png"); TouchStatus.Text = "Touches Ended"; } } // reset our tracking flags touchStartedInside = false; }Obě tyto metody resetují
touchStartedInsidepříznak na false.TouchesEndedzobrazí se takéTouchesEndedna obrazovce.V tuto chvíli je obrazovka s dotykovými ukázkami hotová. Všimněte si, jak se obrazovka mění při interakci s jednotlivými obrázky, jak je znázorněno na následujícím snímku obrazovky:
Ukázky rozpoznávání gest
Předchozí část ukázala, jak přetáhnout objekt po obrazovce pomocí dotykových událostí. V této části se zbavíme dotykových událostí a ukážeme, jak používat následující rozpoznávání gest:
- Při
UIPanGestureRecognizerpřetahování obrázku po obrazovce. - Odpověď
UITapGestureRecognizerna poklepáním na obrazovku
Při implementaci rozpoznávání gest postupujte takto:
Upravte soubor GestureViewController.cs a přidejte následující proměnnou instance:
#region Private Variables private bool imageHighlighted = false; private RectangleF originalImageFrame = RectangleF.Empty; #endregionTuto proměnnou instance potřebujeme, abychom mohli sledovat předchozí umístění image. Rozpoznávání gest posunu použije
originalImageFramehodnotu k výpočtu posunu potřebného k překreslení obrázku na obrazovce.Přidejte do kontroleru následující metodu:
private void WireUpDragGestureRecognizer() { // Create a new tap gesture UIPanGestureRecognizer gesture = new UIPanGestureRecognizer(); // Wire up the event handler (have to use a selector) gesture.AddTarget(() => HandleDrag(gesture)); // to be defined // Add the gesture recognizer to the view DragImage.AddGestureRecognizer(gesture); }Tento kód vytvoří
UIPanGestureRecognizerinstanci a přidá ji do zobrazení. Všimněte si, že k gestu ve formě metodyHandleDragpřiřadíme cíl – tato metoda je k dispozici v dalším kroku.Pokud chcete implementovat HandleDrag, přidejte do kontroleru následující kód:
private void HandleDrag(UIPanGestureRecognizer recognizer) { // If it's just began, cache the location of the image if (recognizer.State == UIGestureRecognizerState.Began) { originalImageFrame = DragImage.Frame; } // Move the image if the gesture is valid if (recognizer.State != (UIGestureRecognizerState.Cancelled | UIGestureRecognizerState.Failed | UIGestureRecognizerState.Possible)) { // Move the image by adding the offset to the object's frame PointF offset = recognizer.TranslationInView(DragImage); RectangleF newFrame = originalImageFrame; newFrame.Offset(offset.X, offset.Y); DragImage.Frame = newFrame; } }Výše uvedený kód nejprve zkontroluje stav rozpoznávání gest a pak obrázek přesune po obrazovce. S tímto kódem teď může ovladač podporovat přetahování jednoho obrázku po obrazovce.
Přidejte obrázek
UITapGestureRecognizer, který změní obrázek zobrazený v DoubleTouchImage. Přidejte do kontroleru následující metoduGestureViewController:private void WireUpTapGestureRecognizer() { // Create a new tap gesture UITapGestureRecognizer tapGesture = null; // Report touch Action action = () => { TouchStatus.Text = string.Format("Image touched at: {0}",tapGesture.LocationOfTouch(0, DoubleTouchImage)); // Toggle the image if (imageHighlighted) { DoubleTouchImage.Image = UIImage.FromBundle("DoubleTapMe.png"); } else { DoubleTouchImage.Image = UIImage.FromBundle("DoubleTapMe_Highlighted.png"); } imageHighlighted = !imageHighlighted; }; tapGesture = new UITapGestureRecognizer(action); // Configure it tapGesture.NumberOfTapsRequired = 2; // Add the gesture recognizer to the view DoubleTouchImage.AddGestureRecognizer(tapGesture); }Tento kód je velmi podobný kódu pro kód,
UIPanGestureRecognizerale místo použití delegáta pro cíl, který používámeAction.Poslední věcí, kterou musíme udělat, je upravit
ViewDidLoadtak, aby volaly metody, které jsme právě přidali. Změňte ViewDidLoad tak, aby připomínal následující kód:public override void ViewDidLoad() { base.ViewDidLoad(); Title = "Gesture Recognizers"; // Save initial state originalImageFrame = DragImage.Frame; WireUpTapGestureRecognizer(); WireUpDragGestureRecognizer(); }Všimněte si také, že inicializujeme hodnotu
originalImageFrame.Spusťte aplikaci a komunikujte se dvěma imagemi. Následující snímek obrazovky je jedním z příkladů těchto interakcí:
Rozpoznávání vlastních gest
V této části použijeme koncepty z předchozích částí k vytvoření vlastního rozpoznávání gest. Rozpoznávání vlastních gest podtřídy UIGestureRecognizera rozpozná, když uživatel na obrazovce nakreslí "V" a pak přepne rastrový obrázek. Následující snímek obrazovky je příkladem této obrazovky:
Pokud chcete vytvořit vlastní rozpoznávání gest, postupujte takto:
Přidejte do projektu
CheckmarkGestureRecognizernovou třídu a nastavte ji jako následující kód:using System; using CoreGraphics; using Foundation; using UIKit; namespace Touch { public class CheckmarkGestureRecognizer : UIGestureRecognizer { #region Private Variables private CGPoint midpoint = CGPoint.Empty; private bool strokeUp = false; #endregion #region Override Methods /// <summary> /// Called when the touches end or the recognizer state fails /// </summary> public override void Reset() { base.Reset(); strokeUp = false; midpoint = CGPoint.Empty; } /// <summary> /// Is called when the fingers touch the screen. /// </summary> public override void TouchesBegan(NSSet touches, UIEvent evt) { base.TouchesBegan(touches, evt); // we want one and only one finger if (touches.Count != 1) { base.State = UIGestureRecognizerState.Failed; } Console.WriteLine(base.State.ToString()); } /// <summary> /// Called when the touches are cancelled due to a phone call, etc. /// </summary> public override void TouchesCancelled(NSSet touches, UIEvent evt) { base.TouchesCancelled(touches, evt); // we fail the recognizer so that there isn't unexpected behavior // if the application comes back into view base.State = UIGestureRecognizerState.Failed; } /// <summary> /// Called when the fingers lift off the screen /// </summary> public override void TouchesEnded(NSSet touches, UIEvent evt) { base.TouchesEnded(touches, evt); // if (base.State == UIGestureRecognizerState.Possible && strokeUp) { base.State = UIGestureRecognizerState.Recognized; } Console.WriteLine(base.State.ToString()); } /// <summary> /// Called when the fingers move /// </summary> public override void TouchesMoved(NSSet touches, UIEvent evt) { base.TouchesMoved(touches, evt); // if we haven't already failed if (base.State != UIGestureRecognizerState.Failed) { // get the current and previous touch point CGPoint newPoint = (touches.AnyObject as UITouch).LocationInView(View); CGPoint previousPoint = (touches.AnyObject as UITouch).PreviousLocationInView(View); // if we're not already on the upstroke if (!strokeUp) { // if we're moving down, just continue to set the midpoint at // whatever point we're at. when we start to stroke up, it'll stick // as the last point before we upticked if (newPoint.X >= previousPoint.X && newPoint.Y >= previousPoint.Y) { midpoint = newPoint; } // if we're stroking up (moving right x and up y [y axis is flipped]) else if (newPoint.X >= previousPoint.X && newPoint.Y <= previousPoint.Y) { strokeUp = true; } // otherwise, we fail the recognizer else { base.State = UIGestureRecognizerState.Failed; } } } Console.WriteLine(base.State.ToString()); } #endregion } }Metoda Reset je volána při
Statezměně vlastnosti buďRecognizedneboEnded. Toto je čas resetovat všechny interní stavy nastavené ve vlastním rozpoznávání gest. Teď může třída začít znovu začít znovu, až uživatel s aplikací komunikuje a bude připraven znovu zjistit gesto.Teď, když jsme definovali vlastní rozpoznávání gest (
CheckmarkGestureRecognizer) upravte soubor CustomGestureViewController.cs a přidejte následující dvě proměnné instance:#region Private Variables private bool isChecked = false; private CheckmarkGestureRecognizer checkmarkGesture; #endregionPokud chcete vytvořit instanci a nakonfigurovat rozpoznávání gest, přidejte do kontroleru následující metodu:
private void WireUpCheckmarkGestureRecognizer() { // Create the recognizer checkmarkGesture = new CheckmarkGestureRecognizer(); // Wire up the event handler checkmarkGesture.AddTarget(() => { if (checkmarkGesture.State == (UIGestureRecognizerState.Recognized | UIGestureRecognizerState.Ended)) { if (isChecked) { CheckboxImage.Image = UIImage.FromBundle("CheckBox_Unchecked.png"); } else { CheckboxImage.Image = UIImage.FromBundle("CheckBox_Checked.png"); } isChecked = !isChecked; } }); // Add the gesture recognizer to the view View.AddGestureRecognizer(checkmarkGesture); }Upravte
ViewDidLoadtak, aby volalyWireUpCheckmarkGestureRecognizer, jak je znázorněno v následujícím fragmentu kódu:public override void ViewDidLoad() { base.ViewDidLoad(); // Wire up the gesture recognizer WireUpCheckmarkGestureRecognizer(); }Spusťte aplikaci a zkuste na obrazovce nakreslit "V". Měla by se zobrazit změna obrázku, jak je znázorněno na následujících snímcích obrazovky:
Výše uvedené tři části ukazují různé způsoby reakce na dotykové události v iOSu: použití dotykových událostí, integrovaných rozpoznávání gest nebo vlastního rozpoznávání gest.





