Handling Rotation Gestures

Panther·2021년 7월 30일
0

https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/handling_uikit_gestures/handling_rotation_gestures

"Measure the relative rotation of two fingers on the screen, and use that motion to rotate your content."

스크린에서 두 손가락의 상대적 회전을 측정하고, 컨텐트를 회전시키기 위해 해당 모션을 사용합니다.

Overview

로테이션 제스쳐는 스크린에 터치하고 있는 두 손가락이 각각 회전하고 있는 경우 발생하는 연속적 제스쳐입니다. 로테이션 제스쳐를 감지하려면 UIRotationGestureRecognizer를 사용해야 합니다.

아래 방법 중 한 가지로 제스쳐 리코그나이저를 구현할 수 있습니다.

  • 코드 작성 방법입니다. 뷰의 addGestureRecognizer(_:) 메소드를 호출합니다.
  • 인터페이스 빌더에서 구현하는 방법입니다. 라이브러리로부터 적합한 객체를 드래그하고 뷰에 드롭합니다.

앱에서 입력으로써 회전의 움직임을 사용하길 원할 때 로테이션 제스쳐 리코그나이저를 사용하시기 바랍니다. 회전이 있는 제스쳐는 보통 스크린에서 객체를 조작하기 위해 사용됩니다. 예를 들어 뷰를 회전시키거나 커스텀 컨트롤의 값을 업데이트하고자 할 때 사용하게 될 것입니다. 로테이션 제스쳐는 연속적입니다. 그렇기 때문에 액션 메소드는 컨텐트를 업데이트할 여지를 줄 수 있도록 회전 값이 바뀔 때마다 호출됩니다.

제스쳐 리코그나이저는 회전 값을 라디언 단위로 알려줍니다. 만약 사용자의 손가락 사이를 선으로 생각하고 있다면, 손가락 처음 위치에서 생성된 선은 측정을 위한 초기 지점을 나타내고, 그러므로 회전 각도를 0으로 나타냅니다. 사용자의 손가락이 움직일 때, 손가락 각각의 새 위치 사이에서 새로운 선이 생성됩니다. 제스쳐 리코그나이저는 초기 선과 각각의 선 사이 각도를 측정하고, 회전 속성에 결과 값을 놓습니다.

로테이션 제스쳐 리코그나이저는 회전이 시작했음을 나타내는 방법으로 사용자의 손가락 위치가 바뀌는 순간 UIGestureRecognizer.State.began 상태에 진입합니다. 초기 변경사항이 이뤄진 후 후속 변경은 제스쳐 리코그나이저가 UIGestureRecognizer.State.changed 상태에 진입하도록 하고, 회전의 각도를 업데이트 합니다. 사용자의 손가락이 스크린으로부터 빠져나오면, 제스쳐 리코그나이저는 UIGestureRecognizer.State.ended 상태에 진입합니다.

Important
컨텐트에 회전 값을 적용할 때 주의를 기울여야 합니다. 예상하지 못한 결과를 가져올 수 있기 때문입니다. 제스쳐 리코그나이저에 의해 보고된 회전은 현재 손가락 위치와 초기 손가락 위치 사이의 각도를 나타냅니다. 만약 각각의 새 회전 값을 컨텐트에 있는 그대로 적용하면, 회전이 지나치게 빠르게 이뤄집니다. 대신 컨텐트의 기존 값을 캐시하고, 기존 값에 회전을 적용해야 하며, 컨텐트에 새 값을 다시 적용해야 합니다. 다른 방법으로 새 변경사항이 적용된 이후 회전 요소를 0.0으로 재설정하는 방법이 있습니다.

Listing 1은 사용자의 손가락을 따라가는 방법으로 뷰를 회전하는 방법을 나타내고 있습니다. 이 액션 메소드는 뷰의 변형에 현재 회전 요소를 적용하고, 이후 제스쳐 리코그나이저의 회전 속성을 0.0으로 재설정합니다. 회전 요소를 재설정하는 것은 제스쳐 리코그나이저가 값이 재설정된 이후 변경의 크기만을 알려줄 수 있도록 합니다. 이는 뷰의 선형적 회전만을 초래하는 경우입니다.

Listing 1 Rotating a view

@IBAction func rotatePiece(_ gestureRecognizer : UIRotationGestureRecognizer) {   // Move the anchor point of the view's layer to the center of the 
   // user's two fingers. This creates a more natural looking rotation. 
   guard gestureRecognizer.view != nil else { return }
        
   if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
      gestureRecognizer.view?.transform = gestureRecognizer.view!.transform.rotated(by: gestureRecognizer.rotation)
      gestureRecognizer.rotation = 0
   }}

로테이션 제스쳐 리코그나이저를 위한 코드가 호출되지 않거나 정확히 작동하지 않는다면, 아래 조건이 true인지 확인하고 수정이 필요하다면 수정하시기 바랍니다.

  • 뷰의 isUserInteractionEnabled 속성이 true인지 확인해야 합니다. 이미지 뷰와 레이블은 이 속성이 기본값으로 false입니다.
  • 적어도 두 손가락이 스크린을 터치하고 있는지 확인해야 합니다.
  • 컨텐트에 회전 요소를 정확히 적용하고 있는지 확인해야 합니다. 오버 로테이션은 같은 회전 값을 2회 이상 적용할 때 발생합니다. 이 문제를 해결하려면, 컨텐트에 현재 회전 값을 적용한 후 회전 속성을 0.0으로 설정해야 합니다.

0개의 댓글