• Home
  • About
    • 황우진 블로그 photo

      황우진 블로그

      경희대학교 컴퓨터공학과 재학중

    • Learn More
    • Email
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

[Booster 2기] iOS 가 사용자의 제스쳐를 인식하는 방법

05 Mar 2020

Reading time ~3 minutes

[부스트코스]iOS 프로그래밍 강좌에 대한 정리글입니다.

[부스트코스]iOS 프로그래밍 Booster 2기 활동 글입니다.

[이전 포스트]iOS 의 다양한 디자인 패턴 알아보기 3


제스쳐(gesture) 란 몸짓이나 손동작 등으로 대화하는 것을 말합니다. iOS 에서는 사용자의 다양한 손동작들을 제스쳐로 미리 정해두었습니다. 한번 클릭하는 것은 Tab 으로, 두번 클릭하는 것은 Double Tab 으로 말입니다. 이 외에도 다양한 제스쳐들이 존재합니다. 드래그, 스와이프, 홀드 등이 있는데 이에 대해서는 Apple 개발자 문서 에서 정말 잘 보여주고 있습니다.

iOS 어플리케이션이 제스쳐들을 인식해서 처리할 수 있도록 하는 것이 바로 제스쳐 인식기(Gesture Recognizer) 입니다. 이 글에서는 이 제스쳐 인식기가 무엇인지 알아보고 직접 구현해보도록 하겠습니다.

제스쳐 인식기

제스쳐 인식기의 동작을 정의하는 클래스는 UIGestureRecognizer 입니다. 이 클래스는 7가지의 하위 클래스로 나뉩니다.

클래스 이름
역할
UITapGestureRecognizer
싱글탭 또는 멀티탭 제스처
UIPinchGestureRecognizer
핀치(Pinch) 제스처
UIRotationGestureRecognizer
정렬 사각형의 상단
UISwipeGestureRecognizer
정렬 사각형의 하단
UIPanGestureRecognizer
텍스트의 하단
UIScreenEdgePanGestureRecognizer
텍스트 시작
UILongPressGestureRecognizer
텍스트 끝

어떤 클래스를 사용할지는 어떤 제스쳐를 사용하는가에 따라 달라집니다. 제스쳐 인식기를 사용하기 위해서는 다음과 같은 메서드를 사용해야 합니다.

@IBAction func myActionMethod()
@IBAction func myActionMethod(_ sender: UIGestureRecognizer)

이는 타겟-액션 연결을 설정한 후에 제스쳐가 인식될 때마다 타겟에 액션 메세지를 전달해줍니다. 만약 제스쳐 인식기가 터치 이벤트를 받았을 경우 뷰는 이벤트를 받을 수 없습니다. 반대로 제스쳐 인식기가 없을 경우 뷰가 터치 이벤트를 받습니다.

이제 직접 제스쳐 인식기를 추가해보도록 하겠습니다. 제스쳐 인식기도 다른 UI 요소들처럼 라이브러리에서 찾을 수 있습니다.

이 중에서 Tab Gesture Recognizer 를 추가하겠습니다. 정상적으로 추가했다면 이제 타겟-액션 설정을 위해 다음과 같이 ViewController.swift 로 드래그 해줍니다. 반드시 Ctrl + 클릭 으로 드래그 하시기 바랍니다.

그러면 액션 메서드를 설정할 수 있는 창이 나타납니다. 저는 다음과 같이 설정하였습니다.

그러면 액션 메서드가 성공적으로 생성됩니다.

@IBAction func tabView(_ sender: UITapGestureRecognizer) {
}

이 메서드가 제대로 동작하는 지 알아보기 위해 print 구문을 추가하도록 하겠습니다.

@IBAction func tabView(_ sender: UITapGestureRecognizer) {
    print("tabView")
}

빌드를 한 후 시뮬레이터에서 화면을 터치하면 해당 메서드가 정상적으로 실행되는 것을 알 수 있습니다.

이 모든 과정을 코드를 통해 설정할 수도 있습니다. 이 때 해야할 것은 타겟과 액션을 생성하고 뷰에 제스쳐 인식기를 연결하는 것입니다. 코드는 다음과 같습니다.

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
        
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapView(gestureRecognizer:)))
        
    self.view.addGestureRecognizer(tapRecognizer)
}

@objc func tapView(gestureRecognizer: UIGestureRecognizer) {
    print("tapView")
}

tapRecognizer 는 현재 뷰(self) 를 타겟으로, tapView 를 액션 메서드로 하는 제스쳐 인식기입니다. 이를 addGestureRecognizer 를 통해 현재 뷰에 연결한 모습입니다.

이 말고도 다른 방법이 하나 더 있습니다. 타겟-액션 패턴이 아닌 델리게이트 패턴으로도 구현할 수 있습니다. UIGestureRecognizerDelegate 를 이용해서 해당 클래스의 기능을 현재 뷰로 위임받은 후에 제스쳐가 들어올 때마다 원하는 동작을 구현해주면 됩니다. 코드로 한번 구현해 보도록 하겠습니다.

class ViewController: UIViewController, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let tapRecognizer = UITapGestureRecognizer()
        
        tapRecognizer.delegate = self
        
        self.view.addGestureRecognizer(tapRecognizer)
    }
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        print("gestureRecognizer")
        
        return true
    }

}

델리게이트 패턴을 위해 클래스 시작 부분에 UIGestureRecognizerDelegate 를 추가하였습니다. 그리고 tapRecognizer 는 이전처럼 타겟이나 액션 없이 그냥 선언하였습니다. 그리고 이를 delegate 를 통해 현재 뷰로 위임하도록 하였습니다.

아래의 gestureRecognizer 함수는 위임한 UIGestureRecognizerDelegate 의 메서드들 중 하나로, 사용자의 터치 제스쳐가 들어왔을 때 동작합니다. 이 메서드는 반드시 true 또는 false 를 반환해야 하는데 그 이유는 이 메서드가 원래 터치 이벤트가 들어왔을 때(shouldReceive touch) 이 이벤트를 받을 지 말지를 반환하도록 하기 때문입니다. 하지만 이 작은 예시에서 반환값은 크게 중요하지 않습니다. 터치가 들어오면 결국 메서드가 수행되기 때문입니다.

어쨋든 이 코드도 화면을 탭할 때마다 정상적으로 메세지를 출력하는 것을 확인할 수 있습니다.


[다음 포스트]iOS 테이블뷰 알아보기


클릭하면 처음 포스트로 돌아갑니다.


boostcourseboosterxcodeswift Share Tweet +1