[UIKit] UIPinchGestureRecognizer에 대하여

Uno·2021년 9월 28일
0

UIKit

목록 보기
4/9
post-thumbnail

(이미지출처 : https://unsplash.com/photos/n4IeCtUhM3A?utm_source=unsplash&utm_medium=referral&utm_content=creditShareLink)

뭔가 Pinch 제스처가 집게발 같아서...


UIPinchGestureRecognizer에 대한 공식문서

공식문서 : https://developer.apple.com/documentation/uikit/uipinchgesturerecognizer

A discrete gesture recognizer that interprets pinching gestures involving two touches.

-> 두 개의 터치를 포함한 "집기" 제스처


정의는 다음과 같습니다.

@MainActor class UIPinchGestureRecognizer : UIGestureRecognizer

UIPinchGestureRecognizerUIGestureRecognizer 의 서브클래스 입니다. (당연하겠죠?)

사용자는 "핀치"(두 손가락을 확대하거나 축소하는 행동을 칭하는 명칭인가봅니다.)를 사용하면 반드시 두 손가락을 사용해야 합니다. 사용자가 두 손가락을 움직일 때, 관습적으로 그것은 줌 아웃이나 줌 인을 뜻하죠.


핀치는 "연속적인 동작 제스쳐" 입니다. 연속적이라는 것은 시작 -> 진행 -> 끝 으로 이뤄져있죠. 그래서 이 제스처는 상태에 대한 3 가지 프로퍼티가 존재합니다.

  1. UIGestureRecognizer.State.began
  2. UIGestureRecognizer.State.changed
  3. UIGestureRecognizer.State.ended


"Topics" 에 보면 2 가지 프로퍼티가 있습니다.

1. var scale: CGFloat
2. var velocity: CGFloat

scale 은 "화면 좌표에서 두 터치 지점을 기준으로 한 축척 비율입니다."

velocity 는 "초당 스케일 팩터의 핀치 속도입니다."



velocity는 잠시 두고, scale을 통해서 화면을 Zoom in&out 기능을 동작할 수 있습니다. 정의만 봐도 아시겠죠. "축척 비율" 이라는 말이 축소화 확대를 의미하죠. 혹시 과거에 한국지리를 배워보셨으면, 익숙하실 축척도 읽는 방법이 생각나시나요? 그 축척입니다. 거기서 1:50,000 지도 / 1:1,000,000 지도 등을 보면서 거리계산하는게 시험문제였던 것 같기도 하네요.

어째든 저 스케일 값을 통해서 확대와 축소를 구현합니다.


코드

제가 추후에 프로젝트로 한번에 설명드릴 예정입니다만, 일단 코드 예시를 보여드리겠습니다.

코드 출처 : https://stackoverflow.com/questions/30014241/uiimageview-pinch-zoom-swift

extension UIImageView {
  func enableZoom() {
    let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(startZooming(_:)))
    isUserInteractionEnabled = true
    addGestureRecognizer(pinchGesture)
  }

  @objc
  private func startZooming(_ sender: UIPinchGestureRecognizer) {
    let scaleResult = sender.view?.transform.scaledBy(x: sender.scale, y: sender.scale)
    guard let scale = scaleResult, scale.a > 1, scale.d > 1 else { return }
    sender.view?.transform = scale
    sender.scale = 1
  }
}

Zoom 기능이 동작하길 원하는 UIImageView에

이미지뷰.enableZoom() 을 실행하면 정상적으로 동작합니다.


하지만, 줌인과 줌아웃의 기준이 정중앙으로만 동작합니다.

해당 문제는 다음 글에서 정리하도록 할게요^^

profile
iOS & Flutter

0개의 댓글