Xamarin.iOS의 터치 이벤트 및 제스처

디바이스와의 모든 물리적 상호 작용의 중심이므로 iOS 애플리케이션에서 터치 이벤트 및 터치 API를 이해하는 것이 중요합니다. 모든 터치 조작에는 개체가 UITouch 포함됩니다. 이 문서에서는 터치를 지원하기 위해 클래스 및 해당 API를 사용하는 UITouch 방법을 알아봅니다. 나중에 제스처를 지원하는 방법을 알아보기 위해 지식을 확장합니다.

터치 사용

UIControl에서 UIKit 서브클래스된 컨트롤은 사용자 조작에 따라 달라지므로 UIKit에 기본 제공된 제스처가 있으므로 Touch를 사용하도록 설정할 필요가 없습니다. 이미 활성화되어 있습니다.

그러나 대부분의 보기는 UIKit 기본적으로 터치를 사용하도록 설정하지 않습니다. 컨트롤에서 터치를 사용하도록 설정하는 방법에는 두 가지가 있습니다. 첫 번째 방법은 다음 스크린샷과 같이 iOS 디자이너의 Property Pad에서 사용자 상호 작용 사용 검사box를 검사 것입니다.

Check the User Interaction Enabled checkbox in the Property Pad of the iOS Designer

컨트롤러를 사용하여 클래스에서 UserInteractionEnabled 속성을 true로 UIView 설정할 수도 있습니다. 코드에서 UI를 만드는 경우 이 작업이 필요합니다.

다음 코드 줄은 예제입니다.

imgTouchMe.UserInteractionEnabled = true;

터치 이벤트

사용자가 화면을 터치하거나, 손가락을 움직이거나, 손가락을 제거할 때 발생하는 터치의 세 가지 단계가 있습니다. 이러한 메서드는 UIView의 기본 클래스인 에 UIResponder정의됩니다. iOS는 터치를 처리하기 위해 연결된 메서드를 UIView 재정의 UIViewController 합니다.

  • TouchesBegan – 화면이 처음 터치될 때 호출됩니다.
  • TouchesMoved – 사용자가 화면을 손가락으로 슬라이딩할 때 터치 위치가 변경되면 호출됩니다.
  • TouchesEnded 또는 TouchesCancelledTouchesEnded 사용자의 손가락이 화면에서 해제될 때 호출됩니다. TouchesCancelled 는 iOS가 터치를 취소하는 경우 호출됩니다. 예를 들어 사용자가 단추에서 손가락을 밀어 누르기를 취소하는 경우와 같습니다.

터치 이벤트는 UIView 스택을 통해 재귀적으로 아래로 이동하여 터치 이벤트가 뷰 개체의 범위 내에 있는지 검사. 이를 적중 테스트라고도 부릅니다. 먼저 맨 위에서 UIViewUIViewController 호출된 다음 뷰 계층 구조의 UIView 아래와 UIViewControllers 위에서 호출됩니다.

UITouch 사용자가 화면을 터치할 때마다 개체가 만들어집니다. 개체에는 UITouch 터치가 발생한 경우, 발생한 위치, 터치가 살짝 밀기인 경우 등과 같은 터치에 대한 데이터가 포함됩니다. 터치 이벤트는 하나 이상의 터치를 포함하는 터치 속성을 NSSet 전달합니다. 이 속성을 사용하여 터치에 대한 참조를 얻고 애플리케이션의 응답을 확인할 수 있습니다.

터치 이벤트 중 하나를 재정의하는 클래스는 먼저 기본 구현을 호출한 다음 이벤트와 연결된 개체를 가져와 UITouch 야 합니다. 첫 번째 터치에 대한 참조를 가져오려면 다음 예제에서 속성을 호출 AnyObject 하고 표시로 UITouch 캐스팅합니다.

public override void TouchesBegan (NSSet touches, UIEvent evt)
{
    base.TouchesBegan (touches, evt);
    UITouch touch = touches.AnyObject as UITouch;
    if (touch != null)
    {
        //code here to handle touch
    }
}

iOS는 화면에서 연속적인 빠른 터치를 자동으로 인식하고 모든 터치를 단일 UITouch 개체에서 한 번의 탭으로 수집합니다. 이렇게 하면 다음 코드와 같이 속성을 검사 만큼 쉽게 두 번 탭할 TapCount 수 검사.

public override void TouchesBegan (NSSet touches, UIEvent evt)
{
    base.TouchesBegan (touches, evt);
    UITouch touch = touches.AnyObject as UITouch;
    if (touch != null)
    {
        if (touch.TapCount == 2)
        {
            // do something with the double touch.
        }
    }
}

멀티 터치

멀티 터치는 컨트롤에서 기본적으로 사용하도록 설정되지 않습니다. 다음 스크린샷과 같이 iOS 디자이너에서 멀티 터치를 사용하도록 설정할 수 있습니다.

Multi-touch enabled in the iOS Designer

다음 코드 줄과 같이 속성을 설정 MultipleTouchEnabled 하여 프로그래밍 방식으로 멀티 터치를 설정할 수도 있습니다.

imgTouchMe.MultipleTouchEnabled = true;

화면에 터치한 손가락 수를 확인하려면 속성의 Count 속성을 UITouch 사용합니다.

public override void TouchesBegan (NSSet touches, UIEvent evt)
{
    base.TouchesBegan (touches, evt);
    lblNumberOfFingers.Text = "Number of fingers: " + touches.Count.ToString();
}

터치 위치 확인

메서드 UITouch.LocationInView 는 지정된 보기 내에서 터치의 좌표를 보유하는 CGPoint 개체를 반환합니다. 또한 메서드 Frame.Contains를 호출하여 해당 위치가 컨트롤 내에 있는지 테스트할 수 있습니다. 다음 코드 조각은 이 예제를 보여줍니다.

if (this.imgTouchMe.Frame.Contains (touch.LocationInView (this.View)))
{
    // the touch event happened inside the UIView imgTouchMe.
}

이제 iOS의 터치 이벤트를 이해했으므로 제스처 인식기를 알아보겠습니다.

제스처 인식기

제스처 인식기는 애플리케이션에서 터치를 지원하도록 프로그래밍 작업을 크게 간소화하고 줄일 수 있습니다. iOS 제스처 인식기는 일련의 터치 이벤트를 단일 터치 이벤트로 집계합니다.

Xamarin.iOS는 다음 기본 제공 제스처 인식기의 기본 클래스로 클래스 UIGestureRecognizer 를 제공합니다.

  • UITapGestureRecognizer – 하나 이상의 탭용입니다.
  • UIPinchGestureRecognizer – 손가락을 꼬집고 퍼뜨리기.
  • UIPanGestureRecognizer – 이동 또는 끌기.
  • UISwipeGestureRecognizer – 임의의 방향으로 살짝 밉니다.
  • UIRotationGestureRecognizer – 시계 방향 또는 시계 반대 방향으로 두 손가락을 회전합니다.
  • UILongPressGestureRecognizer – 길게 누르거나 길게 클릭하여 누르기라고도 합니다.

제스처 인식기를 사용하는 기본 패턴은 다음과 같습니다.

  1. 제스처 인식기를 인스턴스화합니다. 먼저 하위 클래스를 UIGestureRecognizer 인스턴스화합니다. 인스턴스화된 개체는 뷰에 연결되고 뷰가 삭제될 때 가비지 수집됩니다. 이 뷰를 클래스 수준 변수로 만들 필요는 없습니다.
  2. 제스처 설정 구성 – 다음 단계는 제스처 인식기를 구성하는 것입니다. 인스턴스의 동작을 제어하도록 설정할 수 있는 속성 목록은 Xamarin의 설명서 UIGestureRecognizer 및 해당 하위 클래스를 UIGestureRecognizer 참조하세요.
  3. 대상 구성 – 유산 Objective-C 으로 인해 제스처 인식기가 제스처와 일치할 때 Xamarin.iOS는 이벤트를 발생하지 않습니다. UIGestureRecognizer에는 제스처 인식기가 일치할 때 실행할 코드를 사용하여 익명 대리자 또는 Objective-C 선택기를 수락할 수 있는 메서드 AddTarget 가 있습니다.
  4. 제스처 인식기 사용 – 터치 이벤트와 마찬가지로 터치 조작이 활성화된 경우에만 제스처가 인식됩니다.
  5. 보기 에 제스처 인식기를 추가합니다. 마지막 단계는 제스처 인식기 개체를 호출 View.AddGestureRecognizer 하고 전달하여 보기에 제스처를 추가하는 것입니다.

코드에서 구현하는 방법에 대한 자세한 내용은 제스처 인식기 샘플을 참조하세요.

제스처의 대상이 호출되면 발생한 제스처에 대한 참조가 전달됩니다. 이렇게 하면 제스처 대상이 발생한 제스처에 대한 정보를 가져올 수 있습니다. 사용 가능한 정보의 범위는 사용된 제스처 인식기의 유형에 따라 달라집니다. 각 UIGestureRecognizer 하위 클래스에 사용할 수 있는 데이터에 대한 자세한 내용은 Xamarin의 설명서를 참조하세요.

제스처 인식기가 보기에 추가되면 보기(및 그 아래의 모든 보기)는 터치 이벤트를 수신하지 않는다는 점을 기억해야 합니다. 터치 이벤트를 제스처 CancelsTouchesInView 와 동시에 허용하려면 다음 코드와 같이 속성을 false로 설정해야 합니다.

_tapGesture.Recognizer.CancelsTouchesInView = false;

각각 UIGestureRecognizer 에는 제스처 인식기의 상태 대한 중요한 정보를 제공하는 State 속성이 있습니다. 이 속성의 값이 변경될 때마다 iOS는 구독 메서드를 호출하여 업데이트를 제공합니다. 사용자 지정 제스처 인식기가 상태 속성을 업데이트하지 않으면 구독자가 호출되지 않고 제스처 인식기가 쓸모 없게 렌더링됩니다.

제스처는 다음 두 가지 유형 중 하나로 요약할 수 있습니다.

  1. 불연속 – 이러한 제스처는 처음 인식될 때만 발생합니다.
  2. 연속 – 이러한 제스처는 인식되는 한 계속 발생합니다.

제스처 인식기는 다음 상태 중 하나에 있습니다.

  • 가능 – 모든 제스처 인식기의 초기 상태입니다. State 속성의 기본값입니다.
  • 시작 - 연속 제스처가 처음 인식되면 상태가 시작됨으로 설정됩니다. 이렇게 하면 구독자가 제스처 인식이 시작되는 시기와 변경 시기를 구분할 수 있습니다.
  • 변경됨 - 연속 제스처가 시작되었지만 완료되지 않은 후에는 제스처의 예상 매개 변수 내에 있는 한 터치가 이동하거나 변경될 때마다 상태가 변경됨으로 설정됩니다.
  • 취소됨 – 인식기가 시작에서 변경으로 이동한 다음 제스처 패턴에 더 이상 맞지 않도록 터치가 변경된 경우 이 상태가 설정됩니다.
  • 인식됨 – 제스처 인식기가 터치 집합과 일치할 때 상태가 설정되고 제스처가 완료되었음을 구독자에게 알릴 것입니다.
  • 종료 됨 – 인식됨 상태의 별칭입니다.
  • 실패 – 제스처 인식기가 수신 대기 중인 터치와 더 이상 일치하지 않으면 상태가 실패로 변경됩니다.

Xamarin.iOS는 열거형에서 UIGestureRecognizerState 이러한 값을 나타냅니다.

여러 제스처 작업

기본적으로 iOS는 기본 제스처를 동시에 실행할 수 없습니다. 대신 각 제스처 인식기가 비결정적 순서로 터치 이벤트를 수신합니다. 다음 코드 조각에서는 제스처 인식기를 동시에 실행하는 방법을 설명합니다.

gesture.ShouldRecognizeSimultaneously += (UIGestureRecognizer r) => { return true; };

iOS에서 제스처를 사용하지 않도록 설정할 수도 있습니다. 제스처 인식기가 애플리케이션의 상태와 현재 터치 이벤트를 검사하여 제스처를 인식하는 방법과 경우에 대한 결정을 내릴 수 있도록 하는 두 가지 대리자 속성이 있습니다. 두 이벤트는 다음과 같습니다.

  1. ShouldReceiveTouch – 제스처 인식기가 터치 이벤트를 전달하기 직전에 이 대리자를 호출하며, 터치를 검사하고 제스처 인식기에서 처리할 터치를 결정할 수 있는 기회를 제공합니다.
  2. ShouldBegin – 인식기가 가능한 상태에서 다른 상태로 상태를 변경하려고 할 때 호출됩니다. false를 반환하면 제스처 인식기의 상태가 실패로 변경됩니다.

다음 코드 조각에 설명된 UIGestureRecognizerDelegate대로 강력한 형식의 약한 대리자로 이러한 메서드를 재정의하거나 이벤트 처리기 구문을 통해 바인딩할 수 있습니다.

gesture.ShouldReceiveTouch += (UIGestureRecognizer r, UITouch t) => { return true; };

마지막으로 다른 제스처 인식기가 실패하는 경우에만 성공하도록 제스처 인식기를 큐에 대기시킬 수 있습니다. 예를 들어 단일 탭 제스처 인식기가 두 번 탭 제스처 인식기가 실패할 때만 성공해야 합니다. 다음 코드 조각은 이 예제를 제공합니다.

singleTapGesture.RequireGestureRecognizerToFail(doubleTapGesture);

사용자 지정 제스처 만들기

iOS는 몇 가지 기본 제스처 인식기를 제공하지만 특정 경우에 사용자 지정 제스처 인식기를 만들어야 할 수 있습니다. 사용자 지정 제스처 인식기를 만들려면 다음 단계를 수행합니다.

  1. 하위 클래스 .UIGestureRecognizer
  2. 적절한 터치 이벤트 메서드를 재정의합니다.
  3. 기본 클래스의 상태 속성을 통해 인식 상태 버블업합니다.

이에 대한 실질적인 예는 iOS 연습에서 Touch 사용 연습에서 다룹니다.