Sledování vícedotykových prstů v Xamarin.iOS
Tento dokument ukazuje, jak sledovat dotykové události z více prstů.
Existují časy, kdy aplikace pro vícedotykové ovládání potřebuje sledovat jednotlivé prsty, když se pohybují současně na obrazovce. Jednou z typických aplikací je program malování prstem. Chcete, aby uživatel mohl kreslit jedním prstem, ale také kreslit více prsty najednou. Když program zpracovává více dotykových událostí, musí rozlišovat mezi těmito prsty.
Když se prst poprvé dotkne obrazovky, vytvoří UITouch
iOS objekt pro tento prst. Tento objekt zůstává stejný jako prst se pohybuje na obrazovce a potom se zvedne z obrazovky, v jakém okamžiku se objekt odstraní. Chcete-li sledovat prsty, program by se měl vyhnout uložení tohoto UITouch
objektu přímo. Místo toho může použít Handle
vlastnost typu IntPtr
k jedinečné identifikaci těchto UITouch
objektů.
Téměř vždy program, který sleduje jednotlivé prsty, udržuje slovník pro sledování dotykového ovládání. V případě programu pro iOS je klíč slovníku Handle
hodnotou, která identifikuje konkrétní prst. Hodnota slovníku závisí na aplikaci. V ukázkovém programu je každý tah prstem (od dotykového do uvolnění) přidružený k objektu, který obsahuje všechny informace potřebné k vykreslení čáry kreslené tímto prstem. Program definuje malou FingerPaintPolyline
třídu pro tento účel:
class FingerPaintPolyline
{
public FingerPaintPolyline()
{
Path = new CGPath();
}
public CGColor Color { set; get; }
public float StrokeWidth { set; get; }
public CGPath Path { private set; get; }
}
Každá křivka má barvu, šířku tahu a grafický CGPath
objekt pro iOS pro kumulování a vykreslení více bodů čáry při vykreslení.
Veškerý zbytek níže uvedeného kódu je obsažen v derivátu UIView
s názvem FingerPaintCanvasView
. Tato třída udržuje slovník objektů typu FingerPaintPolyline
během doby, kdy jsou aktivně kresleny jedním nebo více prsty:
Dictionary<IntPtr, FingerPaintPolyline> inProgressPolylines = new Dictionary<IntPtr, FingerPaintPolyline>();
Tento slovník umožňuje zobrazení rychle získat FingerPaintPolyline
informace spojené s každým prstem na Handle
základě vlastnosti objektu UITouch
.
Třída FingerPaintCanvasView
také udržuje List
objekt pro křivky, které byly dokončeny:
List<FingerPaintPolyline> completedPolylines = new List<FingerPaintPolyline>();
Objekty v tomto List
pořadí jsou ve stejném pořadí, v jakém byly nakresleny.
FingerPaintCanvasView
přepíše pět metod definovaných View
:
Různé Touches
přepsání hromadí body, které tvoří křivky.
Přepsání [Draw
] nakreslí dokončené čáry a pak probíhající čáry:
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);
}
}
}
Každá z Touches
přepsání potenciálně hlásí akce více prstů označené jedním nebo více UITouch
objekty uloženými v touches
argumentu metody. Přepsání TouchesBegan
prochází těmito objekty. Pro každý UITouch
objekt vytvoří a inicializuje nový FingerPaintPolyline
objekt, včetně uložení počátečního umístění prstu získaného LocationInView
z metody. Tento FingerPaintPolyline
objekt je přidán do InProgressPolylines
slovníku Handle
pomocí vlastnosti UITouch
objektu jako klíč slovníku:
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();
}
Metoda končí voláním SetNeedsDisplay
pro vygenerování volání přepsání Draw
a aktualizací obrazovky.
Při pohybu prstem nebo prsty na obrazovce View
získá více volání k TouchesMoved
přepsání. Toto přepsání UITouch
podobným způsobem prochází objekty uložené v argumentu touches
a přidá aktuální umístění prstu do grafické cesty:
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();
}
Kolekce touches
obsahuje pouze objekty UITouch
pro prsty, které se přesunuly od posledního volání nebo TouchesBegan
TouchesMoved
. Pokud někdy potřebujete UITouch
objekty odpovídající všem prstům aktuálně v kontaktu s obrazovkou, jsou informace k dispozici prostřednictvím AllTouches
vlastnosti UIEvent
argumentu pro metodu.
Přepsání TouchesEnded
má dvě úlohy. Musí přidat poslední bod do grafické cesty a přenést FingerPaintPolyline
objekt ze inProgressPolylines
slovníku completedPolylines
do seznamu:
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();
}
Přepsání TouchesCancelled
se zpracovává jednoduše opuštěním objektu FingerPaintPolyline
ve slovníku:
public override void TouchesCancelled(NSSet touches, UIEvent evt)
{
base.TouchesCancelled(touches, evt);
foreach (UITouch touch in touches.Cast<UITouch>())
{
inProgressPolylines.Remove(touch.Handle);
}
SetNeedsDisplay();
}
Toto zpracování celkem umožňuje ukázkovém programu sledovat jednotlivé prsty a kreslit výsledky na obrazovce:
Teď jste viděli, jak můžete sledovat jednotlivé prsty na obrazovce a rozlišovat mezi nimi.