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ı FingerPaintCanvasView
bir 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 View
tanı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 Handle
UITouch
ö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 TouchesBegan
TouchesMoved
sonra 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 inProgressPolylines
completedPolylines
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:
Artık ekranda tek tek parmaklarını nasıl izleyebilebileceğinizi ve aralarında nasıl ayrım yapabileceğinizi gördünüz.