Xamarin.iOS의 멀티 터치 손가락 추적
이 문서에서는 여러 손가락에서 터치 이벤트를 추적하는 방법을 보여 줍니다.
멀티 터치 애플리케이션이 화면에서 동시에 이동할 때 개별 손가락을 추적해야 하는 경우가 있습니다. 일반적인 애플리케이션 중 하나는 손가락 페인트 프로그램입니다. 사용자가 한 손가락으로 그릴 수 있을 뿐만 아니라 한 번에 여러 손가락으로 그릴 수도 있습니다. 프로그램에서 여러 터치 이벤트를 처리할 때 이러한 손가락을 구분해야 합니다.
손가락이 화면을 처음 터치하면 iOS에서 해당 손가락에 대한 개체를 UITouch
만듭니다. 이 개체는 화면에서 손가락을 이동한 다음 화면에서 들어올려 개체가 삭제되는 시점과 동일하게 기본. 손가락을 추적하려면 프로그램에서 이 UITouch
개체를 직접 저장하지 않아야 합니다. 대신 형식 IntPtr
의 속성을 사용하여 Handle
이러한 UITouch
개체를 고유하게 식별할 수 있습니다.
거의 항상 개별 손가락을 추적하는 프로그램은 터치 추적을 위한 사전을 기본. iOS 프로그램의 경우 사전 키는 특정 손가락을 식별하는 값입니다 Handle
. 사전 값은 애플리케이션에 따라 달라집니다. 샘플 프로그램에서 각 손가락 스트로크(터치에서 해제)는 해당 손가락으로 그린 선을 렌더링하는 데 필요한 모든 정보를 포함하는 개체와 연결됩니다. 이 프로그램은 이 목적을 위해 작은 FingerPaintPolyline
클래스를 정의합니다.
class FingerPaintPolyline
{
public FingerPaintPolyline()
{
Path = new CGPath();
}
public CGColor Color { set; get; }
public float StrokeWidth { set; get; }
public CGPath Path { private set; get; }
}
각 폴리라인에는 색, 스트로크 너비 및 iOS 그래픽 CGPath
개체가 그려질 때 선의 여러 점을 누적하고 렌더링할 수 있습니다.
아래에 표시된 코드의 나머지 모든 항목은 명명FingerPaintCanvasView
된 파생 항목에 UIView
포함되어 있습니다. 이 클래스는 기본 하나 이상의 손가락으로 적극적으로 그려지는 동안 형식 FingerPaintPolyline
개체의 사전을 포함합니다.
Dictionary<IntPtr, FingerPaintPolyline> inProgressPolylines = new Dictionary<IntPtr, FingerPaintPolyline>();
이 사전을 사용하면 개체의 속성 UITouch
에 Handle
따라 각 손가락과 연결된 정보를 빠르게 가져올 FingerPaintPolyline
수 있습니다.
또한 클래스는 FingerPaintCanvasView
완료된 폴리라인에 대한 개체를 기본.List
List<FingerPaintPolyline> completedPolylines = new List<FingerPaintPolyline>();
이 List
개체의 개체는 그렸던 순서와 같습니다.
FingerPaintCanvasView
는 다음으로 정의된 View
5개의 메서드를 재정의합니다.
다양한 Touches
재정의는 폴리라인을 구성하는 점을 누적합니다.
[Draw
] 재정의는 완성된 폴리라인과 진행 중인 폴리라인을 그립니다.
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);
}
}
}
각 재정의는 인수에 Touches
저장된 하나 이상의 UITouch
개체로 표시된 여러 손가락의 동작을 메서드에 touches
보고할 수 있습니다. 재정의는 TouchesBegan
이러한 개체를 반복합니다. 각 UITouch
개체에 대해 메서드는 메서드에서 LocationInView
가져온 손가락의 초기 위치를 저장하는 것을 포함하여 새 FingerPaintPolyline
개체를 만들고 초기화합니다. 이 FingerPaintPolyline
개체는 개체의 InProgressPolylines
UITouch
속성을 사전 키로 사용하여 Handle
사전에 추가됩니다.
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();
}
메서드는 재정의에 대한 호출을 생성하고 화면을 업데이트하기 위해 Draw
호출 SetNeedsDisplay
하여 종료됩니다.
손가락 또는 손가락이 화면에서 이동하면 재정의 View
에 대한 여러 호출을 TouchesMoved
가져옵니다. 이 재정의는 인수에 touches
저장된 개체를 UITouch
반복하고 그래픽 경로에 손가락의 현재 위치를 추가합니다.
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();
}
컬렉션에는 touches
마지막 호출 TouchesBegan
이후 이동한 손가락에 대한 개체만 UITouch
포함됩니다TouchesMoved
. 현재 화면과 접촉하는 모든 손가락에 해당하는 개체가 필요한 UITouch
경우 해당 정보는 메서드에 대한 인수의 UIEvent
속성을 통해 AllTouches
사용할 수 있습니다.
재정의에는 TouchesEnded
두 개의 작업이 있습니다. 그래픽 경로에 마지막 점을 추가하고 사전에서 목록으로 개체를 inProgressPolylines
completedPolylines
전송 FingerPaintPolyline
해야 합니다.
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();
}
재정의는 TouchesCancelled
단순히 사전에서 개체를 FingerPaintPolyline
중단하여 처리됩니다.
public override void TouchesCancelled(NSSet touches, UIEvent evt)
{
base.TouchesCancelled(touches, evt);
foreach (UITouch touch in touches.Cast<UITouch>())
{
inProgressPolylines.Remove(touch.Handle);
}
SetNeedsDisplay();
}
이 처리를 통해 샘플 프로그램은 개별 손가락을 추적하고 화면에 결과를 그릴 수 있습니다.
이제 화면에서 개별 손가락을 추적하고 구분하는 방법을 살펴보았습니다.