Gesture Recognizer 알아보기

고라니·2023년 7월 13일
0

TIL

목록 보기
11/67

GestureRecognizer란?

GestureRecognizer는 제스처 인식기라고도 하며 여러 터치 이벤트를 인식한다. 특정 제스처 이벤트가 일어나면 각 타겟에 맞는 액션 메시지를 보내 제스처 관련 이벤트를 처리한다.

  • UIGestureRecognizer class
    GestureRecognizer 클래스는 위에서 설명한 제스처 인식기를 활용하기 위한 클래스이다. 여러 하위 클래스들은 다양한 제스처를 인식하고 처리하며, 델리게이트 객체를 활용하여 더욱 세밀한 사용자화가 가능하다.

왜 사용할까?

사용자의 터치 이벤트를 간편하게 제어하고 구현할 수 있도록 도와준다. 복잡한 터치 이벤트 처리를 직접 처리하지 않고 GestureRecognizer를 통해 단지 제스처가 발생했을 때 어떤 동작을 해야하는지만 구현하면 된다. 결국 터치 기반 인터페이스를 보다 쉽게 만들 수 있게 도와준다.

주의할 점은 사용자가 새로운 앱을 배우는데 드는 시간을 줄일 수 있도록 일관된 제스처를 제공해야 한다는 것이다.

세부 내용들 알아보기

UIGestureRecognizer의 서브클래스들

UIGestureRecognizer의 구체적인 서브클래스에는 다음과 같은 것들이 있다.

// 탭 제스처를 인식
class UITapGestureRecognizer: UIGestureRecognizer

// 핀치(두 손가락을 벌리거나 좁히는) 제스처를 인식
class UIPinchGestureRecognizer: UIGestureRecognizer

// 회전 제스처를 인식
class UIRotationGestureRecognizer: UIGestureRecognizer

// 스와이프 제스처를 인식
class UISwipeGestureRecognizer: UIGestureRecognizer

// 팬(드래그) 제스처를 인식
class UIPanGestureRecognizer: UIGestureRecognizer

// 화면 가장자리 팬 제스처를 인식
class UIScreenEdgePanGestureRecognizer: UIGestureRecognizer

// 길게 누르는 제스처를 인식
class UILongPressGestureRecognizer: UIGestureRecognizer

// 호버(마우스나 펜 같은 포인터 장치를 사용할 때, 화면 위에서 움직이는) 제스처를 인식
class UIHoverGestureRecognizer: UIGestureRecognizer

UIGestureRecognizer의 주요 메서드

// 타깃-액션 방식을 통해 제스처 인식기를 초기화, 이 메서드는 지정한 타겟에 해한 액션(메서드)를 호출
init(target: Any?, action: Selector?)

// 제스처가 발생한 위치 반환
func location(in: UIView?) -> CGPoint

// 제스처 인식기에 타깃과 액션 추가, 이벤트가 발생했을 때 실행할 메서드 정의 가능
func addTarget(Any, action: Selector)

// 제스처 인식기에서 특정 타깃과 액션을 제거
func removeTarget(Any?, action: Selector?)

// 여러 제스처 인식기가 있을 때, 제스처 인식기간의 의존성 설정
func require(toFail: UIGestureRecognizer)

UIGestureRecognizer의 주요 프로퍼티

// 제스처 인식기의 현재 상태(제스처를 인식하는지 실패했는지)
var state: UIGestureRecognizerState

// 제스처 인식기가 현재 연결되어 있는 뷰
var view: UIView?

// 제스처 인식기가 활성화되어 있는지, 제스처 인식기를 활성화 하거나 비활성화 가능
var isEnabled: Bool

// 제스처 인식이 완료되면 해당 뷰에 더이상 터치 이벤트가 전달되지 않도록 설정(기본값은 true)
var cancelsTouchInView: Bool

// 제스처 인식이 'began' 단계에 도달했을 때 해당 뷰에 터치 이벤트의 전달을 지연할지 결정
var delaysTouchesBegan: Bool

// 제스처 인식이 'ended' 단계에 도달했을 때 해당 뷰에 터치 이벤트의 전달을 지연할지 결정
var delaysTouchesEnded: Bool

사용해보기

인터페이스 빌더르 사용하여 구현하기

아래의 예시에서는 각각 tap, swipe, 그리고 long press를 인터페이스 빌더를 통해 구현하는 방법이다.


라이브러리에 제스처인식기의 하위 컴포넌트들이 있다.



하나의 뷰에 여러개의 제스처인식기 지정이 가능하다.


원하는 뷰에 드래그 하여 타겟을 지정할 수 있다.

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func tapView(_ sender: UITapGestureRecognizer) {
        print("뷰가 탭 되었다.")
    }
    
    @IBAction func swipeView(_ sender: UISwipeGestureRecognizer) {
        print("뷰가 스와이프 되었다.")
    }

    @IBAction func longPressView(_ sender: UILongPressGestureRecognizer) {
        print("뷰가 길게 눌렸다.")
    }
}

위의 예시와 같이 제스처 인식기는 간단하게 탭, 스와이프, 긴 클릭 등 사용자의 제스처에 따라 다양한 액션을 취할 수 있도록 도와준다.

코드로 구현하기

let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapView(_:)))

사용할 제스처인식기를 타겟과 액션 메서드를 지정하여 초기화 해준다.

view.addGestureRecognizer(tapGestureRecognizer)

타겟이 된 뷰가 사용할 제스처인식기를 추가한다.

인터페이스 빌더에서 구현해 보았던 tapGestureRecognizer과 동일하게 화면을 탭하면 해당 메서드가 호출된다.

델리게이트를 이용하여 사용자화 하기

class ViewController: UIViewController, UIGestureRecognizerDelegate { ... }

우선 델리게이트를 이용하기 위해 UIGestureRecognizerDelegate를 채택한다.
UITapGestureRecognizer는 UIGestureRecognizer의 서브클래스이기 때문에 UIGestureRecognizerDelegate 메서드를 사용할 수 있다.

let tapGestureRecognizer = UITapGestureRecognizer()
tapGestureRecognizer.delegate = self

이번에는 델리게이트를 이용할 것이기 때문에 타겟-액션을 지정하지 않고 초기화 하고 해당 제스처인식기의 대리자로 해당 뷰를 할당해준다.

결과적으로 많은 UIGestureRecognizerDelegate 메서드를 확인할 수 있다. 이 중 위에서 구현한 기능과 같은 기능을 하는 메서드를 사용해보겠다.

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        print("뷰가 탭 되었다")
        return true
    }

같은 결과를 출력하는것을 확인 했다.

결론

제스처 인식기는 iOS 앱에서 사용자의 제스처를 감지하고 응답하는 중요한 도구다.
UIGestureRecognizer 클래스와 하위 클래스들은 다양한 제스처를 인식하고, 처티기반 인터페이스를 쉽게 만들 수 있도록 도와준다. 사용자의 제스처에 따른 적절한 반응을 구현하기 위해 제스처 인식기를 잘 이해하고 활용하면 좀더 사용자 친화적인 앱을 개발할 수 있다.

profile
🍎 무럭무럭

0개의 댓글