Aracılığıyla paylaş


İzlenecek yol: Xamarin.iOS'ta Dokunmayı Kullanma

Bu izlenecek yol, farklı türlerdeki dokunma olaylarına yanıt veren kodun nasıl yazıldığını gösterir. Her örnek ayrı bir ekranda bulunur:

Her bölüm, kodu sıfırdan yazmaya ilişkin yönergeler içerir.

Görsel taslakta kod eklemek için aşağıdaki yönergeleri izleyin ve iOS'ta kullanılabilen farklı dokunma olayı türleri hakkında bilgi edinin.

Dokunma Örnekleri

Bu örnekte bazı dokunma API'lerini göstereceğiz. Dokunma olaylarını uygulamak için gereken kodu eklemek için şu adımları izleyin:

  1. Proje Touch_Start açın. Önce her şeyin yolunda olduğundan emin olmak için projeyi çalıştırın ve Dokunma Örnekleri düğmesine dokunun. Aşağıdakine benzer bir ekran görmeniz gerekir (düğmelerden hiçbiri çalışmasa da):

    Çalışmayan düğmelerle çalışan örnek uygulama

  2. dosya TouchViewController.cs düzenleyin ve sınıfına TouchViewControlleraşağıdaki iki örnek değişkenini ekleyin:

    #region Private Variables
    private bool imageHighlighted = false;
    private bool touchStartedInside;
    #endregion
    
  3. TouchesBegan Aşağıdaki kodda gösterildiği gibi yöntemini uygulayın:

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

    Bu yöntem bir UITouch nesneyi denetleyerek çalışır ve nesnenin mevcut olup olmadığını kontrol ederek dokunmanın oluştuğu yere göre bazı eylemler gerçekleştirin:

    • TouchImage içinde – metni Touches Began bir etikette görüntüleyin ve resmi değiştirin.
    • DoubleTouchImage içinde – hareket iki kez dokunmaysa görüntülenen görüntüyü değiştirin.
    • DragImage içinde – dokunmanın başladığını belirten bir bayrak ayarlayın. yöntemi TouchesMoved , bir sonraki adımda göreceğimiz gibi ekranda hareket ettirilip taşınmaması gerektiğini belirlemek DragImage için bu bayrağı kullanır.

    Yukarıdaki kod yalnızca tek tek dokunmalarla ilgilidir, kullanıcı parmağı ekranda hareket ettiriyorsa hala bir davranış yoktur. Harekete yanıt vermek için aşağıdaki kodda gösterildiği gibi uygulayın TouchesMoved :

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

    Bu yöntem bir UITouch nesne alır ve dokunmanın nerede gerçekleştiğini kontrol eder. Dokunma içinde TouchImagegerçekleştiyse, ekranda Dokunan Dokunuyor metni görüntülenir.

    Doğruysa touchStartedInside , kullanıcının parmağının üzerinde DragImage olduğunu ve hareket ettirdiğini biliyoruz. Kullanıcı parmağı ekranda hareket ettikçe kod hareket eder DragImage .

  4. Kullanıcı parmağını ekrandan kaldırdığında veya iOS dokunma olayını iptal ettiğinde olayı işlememiz gerekir. Bunun için aşağıda gösterildiği gibi ve TouchesCancelled uygulayacağızTouchesEnded:

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

    Bu yöntemlerin her ikisi de bayrağı false olarak touchStartedInside sıfırlar. TouchesEnded ekranda da görüntülenir TouchesEnded .

  5. Bu noktada Dokunmatik Örnekler ekranı tamamlanmıştır. Aşağıdaki ekran görüntüsünde gösterildiği gibi, görüntülerin her biriyle etkileşim kurarken ekranın nasıl değiştiğine dikkat edin:

    Başlangıç uygulaması ekranı

    Kullanıcı bir düğmeyi sürükledikten sonra ekran

Hareket Tanıma Örnekleri

Önceki bölümde , dokunma olaylarını kullanarak bir nesnenin ekranda nasıl sürüklendiği gösterilmiştir. Bu bölümde dokunma olaylarından kurtulacak ve aşağıdaki hareket tanıyıcılarının nasıl kullanılacağını göstereceğiz:

  • Bir UIPanGestureRecognizer görüntüyü ekranın çevresine sürüklemek için.
  • İki UITapGestureRecognizer kez dokunmaya yanıt vermek için, ekrana dokunun.

Hareket tanıyıcıları uygulamak için şu adımları izleyin:

  1. Dosya GestureViewController.cs düzenleyin ve aşağıdaki örnek değişkenini ekleyin:

    #region Private Variables
    private bool imageHighlighted = false;
    private RectangleF originalImageFrame = RectangleF.Empty;
    #endregion
    

    Görüntünün önceki konumunu izlemek için bu örnek değişkenine ihtiyacımız var. Kaydırma hareketi tanıyıcısı originalImageFrame , ekrandaki görüntüyü yeniden çizmek için gereken uzaklığı hesaplamak için değerini kullanır.

  2. Denetleyiciye aşağıdaki yöntemi ekleyin:

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

    Bu kod bir UIPanGestureRecognizer örneği oluşturur ve bir görünüme ekler. Harekete yöntemi HandleDrag biçiminde bir hedef atadığımıza dikkat edin; bu yöntem bir sonraki adımda sağlanır.

  3. HandleDrag'ı uygulamak için denetleyiciye aşağıdaki kodu ekleyin:

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

    Yukarıdaki kod önce hareket tanıyıcının durumunu denetler ve ardından görüntüyü ekranda hareket ettirecektir. Bu kod yerine yerleştirildiyse denetleyici artık tek bir görüntüyü ekranda sürüklemeyi destekleyebilir.

  4. DoubleTouchImage'da görüntülenen görüntüyü değiştirecek bir UITapGestureRecognizer ekleyin. Denetleyiciye GestureViewController aşağıdaki yöntemi ekleyin:

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

    Bu kod için koda çok benzer, ancak bir hedef için UIPanGestureRecognizer temsilci kullanmak yerine bir Actionkullanıyoruz.

  5. Yapmamız gereken son şey, yeni eklediğimiz yöntemleri çağıracak şekilde değiştirmektir ViewDidLoad . ViewDidLoad dosyasını aşağıdaki koda benzeyecek şekilde değiştirin:

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
    
        Title = "Gesture Recognizers";
    
        // Save initial state
        originalImageFrame = DragImage.Frame;
    
        WireUpTapGestureRecognizer();
        WireUpDragGestureRecognizer();
    }
    

    değerini originalImageFramede başlatdığımıza dikkat edin.

  6. Uygulamayı çalıştırın ve iki görüntüyle etkileşime geçin. Aşağıdaki ekran görüntüsü, bu etkileşimlerin bir örneğidir:

    Bu ekran görüntüsü sürükleme etkileşimlerini gösterir

Özel Hareket Tanıyıcı

Bu bölümde, özel hareket tanıyıcısı oluşturmak için önceki bölümlerdeki kavramları uygulayacağız. Özel hareket tanıyıcı alt sınıflarına UIGestureRecognizersahip olur ve kullanıcı ekranda bir "V" çizip bit eşlemi değiştirdiğinde bunu tanır. Aşağıdaki ekran görüntüsü bu ekranın bir örneğidir:

Kullanıcı ekranda bir V çizdiğinde uygulama bunu algılar

Özel hareket tanıyıcısı oluşturmak için şu adımları izleyin:

  1. adlı CheckmarkGestureRecognizerprojeye yeni bir sınıf ekleyin ve aşağıdaki kod gibi görünmesini sağlayın:

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

    Özelliği veya Endedolarak değiştiğinde StateRecognized Reset yöntemi çağrılır. Bu, özel hareket tanıyıcısında ayarlanan tüm iç durumları sıfırlamanın zamanıdır. Artık kullanıcı uygulamayla bir sonraki etkileşiminde sınıf yeni bir başlangıç yapabilir ve hareketi tanımayı yeniden denemeye hazır olabilir.

  2. Özel hareket tanıyıcıCheckmarkGestureRecognizer () tanımladığımıza göre CustomGestureViewController.cs dosyasını düzenleyin ve aşağıdaki iki örnek değişkenini ekleyin:

    #region Private Variables
    private bool isChecked = false;
    private CheckmarkGestureRecognizer checkmarkGesture;
    #endregion
    
  3. Hareket tanıyıcımızın örneğini oluşturup yapılandırmak için denetleyiciye aşağıdaki yöntemi ekleyin:

    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);
    }
    
  4. Aşağıdaki kod parçacığında gösterildiği gibi öğesini çağırması WireUpCheckmarkGestureRecognizeriçin düzenleyinViewDidLoad:

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
    
        // Wire up the gesture recognizer
        WireUpCheckmarkGestureRecognizer();
    }
    
  5. Uygulamayı çalıştırın ve ekranda bir "V" çizmeyi deneyin. Aşağıdaki ekran görüntülerinde gösterildiği gibi görüntüde değişiklik olduğunu görmeniz gerekir:

    Düğme işaretli

    Düğmenin işareti kaldırıldı

Yukarıdaki üç bölümde, iOS'ta dokunma olaylarına yanıt vermenin farklı yolları gösterilmiştir: dokunma olaylarını kullanma, yerleşik hareket tanıyıcıları veya özel hareket tanıyıcı ile.