Aracılığıyla paylaş


Xamarin.iOS'ta Çoklu Dokunmatik Parmak İzleme

Bu belgede, dokunma olaylarını birden çok parmaktan izleme gösterilmektedir

Çok dokunmalı bir uygulamanın ekranda aynı anda hareket ederken tek tek parmaklarını izlemesi gereken zamanlar vardır. Tipik bir uygulama parmak boyama programıdır. Kullanıcının tek parmakla çizim yapabilmesini ancak aynı anda birden çok parmakla çizim yapabilmesini istiyorsunuz. Programınız birden çok dokunma olayını işlerken bu parmaklar arasında ayrım yapması gerekir.

Bir parmak ekrana ilk kez dokunduğunda, iOS bu parmak için bir UITouch nesne oluşturur. Bu nesne, parmağın ekranda hareket ettiği ve ardından nesnenin atıldığı ekrandan kaldırıldığı gibi kalır. Bir program, parmaklarını izlemek için bu UITouch nesneyi doğrudan depolamaktan kaçınmalıdır. Bunun yerine, bu UITouch nesneleri benzersiz olarak tanımlamak için türünün IntPtr özelliğini kullanabilirHandle.

Neredeyse her zaman, tek tek parmaklarını izleyen bir program, dokunma izleme için bir sözlük tutar. Bir iOS programı için sözlük anahtarı, belirli bir parmağı tanımlayan değerdir Handle . Sözlük değeri uygulamaya bağlıdır. Örnek programda, her parmak vuruşu (dokunmadan yayına) bu parmakla çizilen çizgiyi işlemek için gerekli tüm bilgileri içeren bir nesneyle ilişkilendirilir. Program bu amaçla küçük FingerPaintPolyline bir sınıf tanımlar:

class FingerPaintPolyline
{
    public FingerPaintPolyline()
    {
        Path = new CGPath();
    }

    public CGColor Color { set; get; }

    public float StrokeWidth { set; get; }

    public CGPath Path { private set; get; }
}

Her çok çizgi, çizilirken çizginin birden çok noktasında birikip işlemek için bir renk, vuruş genişliği ve bir iOS grafik CGPath nesnesine sahiptir.

Aşağıda gösterilen kodun geri kalanı adlı FingerPaintCanvasViewbir UIView türev içinde yer alır. Bu sınıf, bir veya daha fazla parmakla etkin olarak çizildikleri süre boyunca türündeki FingerPaintPolyline nesnelerin bir sözlüğünü tutar:

Dictionary<IntPtr, FingerPaintPolyline> inProgressPolylines = new Dictionary<IntPtr, FingerPaintPolyline>();

Bu sözlük, görünümün nesnenin FingerPaintPolyline özelliğine göre Handle her parmakla ilişkili bilgileri hızla elde etmesini UITouch sağlar.

sınıfı, FingerPaintCanvasView tamamlanmış olan çok çizgili değerler için de bir List nesne tutar:

List<FingerPaintPolyline> completedPolylines = new List<FingerPaintPolyline>();

Bunun List içindeki nesneler, çizildiği sıradadır.

FingerPaintCanvasView tarafından Viewtanımlanan beş yöntemi geçersiz kılar:

Çeşitli Touches geçersiz kılmalar, çoklu çizgileri oluşturan noktaları biriktirir.

[Draw] geçersiz kılması tamamlanmış çok çizgileri ve devam eden çok çizgili çizgileri çizer:

public override void Draw(CGRect rect)
{
    base.Draw(rect);

    using (CGContext context = UIGraphics.GetCurrentContext())
    {
        // Stroke settings
        context.SetLineCap(CGLineCap.Round);
        context.SetLineJoin(CGLineJoin.Round);

        // Draw the completed polylines
        foreach (FingerPaintPolyline polyline in completedPolylines)
        {
            context.SetStrokeColor(polyline.Color);
            context.SetLineWidth(polyline.StrokeWidth);
            context.AddPath(polyline.Path);
            context.DrawPath(CGPathDrawingMode.Stroke);
        }

        // Draw the in-progress polylines
        foreach (FingerPaintPolyline polyline in inProgressPolylines.Values)
        {
            context.SetStrokeColor(polyline.Color);
            context.SetLineWidth(polyline.StrokeWidth);
            context.AddPath(polyline.Path);
            context.DrawPath(CGPathDrawingMode.Stroke);
        }
    }
}

Geçersiz kılmaların her biri, yöntemin Touches bağımsız değişkeninde depolanan bir veya daha fazla UITouch nesne tarafından gösterilen birden çok parmağın touches eylemlerini bildiriyor olabilir. Geçersiz TouchesBegan kılmalar bu nesneler arasında döngü oluşturur. Her UITouch nesne için yöntemi, yönteminden LocationInView alınan parmağın ilk konumunu depolama da dahil olmak üzere yeni FingerPaintPolyline bir nesne oluşturur ve başlatır. Bu FingerPaintPolyline nesne, sözlük anahtarı olarak nesnesinin HandleUITouch özelliği kullanılarak sözlüğe eklenirInProgressPolylines:

public override void TouchesBegan(NSSet touches, UIEvent evt)
{
    base.TouchesBegan(touches, evt);

    foreach (UITouch touch in touches.Cast<UITouch>())
    {
        // Create a FingerPaintPolyline, set the initial point, and store it
        FingerPaintPolyline polyline = new FingerPaintPolyline
        {
            Color = StrokeColor,
            StrokeWidth = StrokeWidth,
        };

        polyline.Path.MoveToPoint(touch.LocationInView(this));
        inProgressPolylines.Add(touch.Handle, polyline);
    }
    SetNeedsDisplay();
}

yöntemi, geçersiz kılmaya bir çağrı oluşturmak ve ekranı güncelleştirmek için Draw çağrısı SetNeedsDisplay yaparak sona erer.

Parmak veya parmaklar ekranda hareket ettikçe, View geçersiz kılmaya TouchesMoved birden çok çağrı alır. Bu geçersiz kılma benzer şekilde bağımsız değişkende touches depolanan nesneler arasında UITouch döngü oluşturur ve parmağın geçerli konumunu grafik yoluna ekler:

public override void TouchesMoved(NSSet touches, UIEvent evt)
{
    base.TouchesMoved(touches, evt);

    foreach (UITouch touch in touches.Cast<UITouch>())
    {
        // Add point to path
        inProgressPolylines[touch.Handle].Path.AddLineToPoint(touch.LocationInView(this));
    }
    SetNeedsDisplay();
}

Koleksiyon yalnızca touches veya öğesine yapılan son çağrıdan TouchesBeganTouchesMovedsonra taşınan parmaklar için bu UITouch nesneleri içerir. Şu anda ekranla temas halinde olan tüm parmaklara karşılık gelen nesnelere ihtiyacınız UITouch olursa, bu bilgiler yöntemin bağımsız değişkeninin UIEvent özelliği aracılığıyla AllTouches kullanılabilir.

Geçersiz TouchesEnded kılmanın iki işi vardır. Grafik yoluna son noktayı eklemeli ve nesneyi sözlükten inProgressPolylinescompletedPolylines listeye aktarmalıdırFingerPaintPolyline:

public override void TouchesEnded(NSSet touches, UIEvent evt)
{
    base.TouchesEnded(touches, evt);

    foreach (UITouch touch in touches.Cast<UITouch>())
    {
        // Get polyline from dictionary and remove it from dictionary
        FingerPaintPolyline polyline = inProgressPolylines[touch.Handle];
        inProgressPolylines.Remove(touch.Handle);

        // Add final point to path and save with completed polylines
        polyline.Path.AddLineToPoint(touch.LocationInView(this));
        completedPolylines.Add(polyline);
    }
    SetNeedsDisplay();
}

Geçersiz TouchesCancelled kılma yalnızca sözlükteki nesne bırakılarak FingerPaintPolyline işlenir:

public override void TouchesCancelled(NSSet touches, UIEvent evt)
{
    base.TouchesCancelled(touches, evt);

    foreach (UITouch touch in touches.Cast<UITouch>())
    {
        inProgressPolylines.Remove(touch.Handle);
    }
    SetNeedsDisplay();
}

Bu işlem, örnek programın tek tek parmaklarını izlemesine ve sonuçları ekrana çizmesine olanak tanır:

Tek tek parmaklarını izleme ve sonuçları ekranda çizme

Artık ekranda tek tek parmaklarını nasıl izleyebilebileceğinizi ve aralarında nasıl ayrım yapabileceğinizi gördünüz.