Gesture Recognizer Example

Doehyung Kim·2020년 3월 1일
2

1. Gesture Recognizer Example

  • 상황 설명: 상위 뷰로 GreyView(customized)가 있고 이 뷰의 하위 뷰로 MyLabel, MyButton, MyTextField(역시 모두 cutomized)가 있다.

  • 앱 화면

스크린샷 2020-03-01 오후 1 40 28
  • Tap Gesture Recognizer가 참조하는 객체는 MyTextField 객체로 두었고, send Action 설정은 ViewController로 두었다.
스크린샷 2020-03-01 오후 1 32 17
  • tapField는 Tap Gesture Recognizer와 연결된 action 함수이다.(send Action)
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func tapField(_ sender: UITapGestureRecognizer) {
        print(#file, #line, #function, #column)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        print(#file, #line, #function, #column)
    }
}
  • 실행된 앱에서 MyTextField가 위치한 곳에 터치를 하면 결과가 어떻게 될까?

실행결과 (콘솔 화면)

/Users/kimdo/workspace/ResponderSample/ResponderSample/View/MyTextField.swift 15 touchesBegan(_:with:) 40
/Users/kimdo/workspace/ResponderSample/ResponderSample/ViewController.swift 18 tabField(_:) 40

=> 해당 터치를 TapGestureRecognizer가 tap event로 인식하여 해당 액션 메시지를 viewController에게 보내게 되고, tabField가 호출이 되어 /Users/kimdo/workspace/ResponderSample/ResponderSample/ViewController.swift 18 tabField(_:) 40이 출력된다.

2. Question

근데 이상한 점이 없는가? 본래 UITextField는 UIContorl로서 tap event를 받으면 키보드를 올리게 되어있다. 하지만 위의 프로그램을 실행하고 MyTextField를 터치하니 tapField만 호출이 되고 키보드는 더 이상 올라오지 않는다. 왜 그럴까?

3. Answer

=> 애플의 Article을 보면 해답을 알 수 있다.

Gesture recognizers receive touch and press events before their view does. If a view's gesture recognizers fail to recognize a sequence of touches, UIKit sends the touches to the view. If the view does not handle the touches, UIKit passes them up the responder chain.

(Gesture recognizer는 touch, press 이벤트를 그들이 참조하는 뷰들보다 먼저 받습니다. 만약 뷰의 Gesture recongnizer가 일련의 touch들을 인식하는데 실패하면, UIKit는 뷰에게 touch들을 전달합니다. 만약 뷰가 일련의 touch들을 다루지 않으면, UIKit는 responder chain을 따라 해당 touch들을 올립니다.)

=> 따라서 MyTextField가 위치한 곳을 터치하면 해당 터치를 Tap Gesture Recognizer가 tap event로 인식하여 viewController에게 send Action을 하는 것이다. 반면에 기존에 UIControl로서 tap event를 받으면 키보드를 올리는 MyTextField는 Tap Gesture Recognizer가 해당 tap event를 처리했으니 tap event를 수신하지 못하므로 키보드는 올라오지 않는 것이다.

=> 반면에 MyTextField클래스가 재정의한 touchesBegan은 호출이 되는데, 그 이유는 해당 터치를 touch event로서 tap gesture recognizer가 인식을 하지 못하므로 뷰인 MyTextField 객체가 touch event를 수신하고 UIResponder로서 재정의된 touchesBegan을 호출하기 때문이다.

4. Resource

ResponderSample.zip

5. Reference

profile
해피 코딩

0개의 댓글