티스토리 뷰

https://developer.apple.com/documentation/uikit/uigesturerecognizer/state

UIGestureRecognizer.State

GestureRecognizer는 탭이나 스와이프와 같은 이벤트를 인식하지만, 제스처 내의 변경 사항은 보고하지 않습니다.

즉, 각 제스처들은 Began이나 Changed상태를 통해 전환되지 않으며, failed이나 canceled 할 수 없습니다.

case possible

  • GestureRecognizer가 아직 제스처를 인식하지 않은 상태, 하지만 터치 이벤트를 평가할 수 있는 상태 (default state)

case began

  • GestureRecognizer가 연속적인 제스처(continuous gesture) 터치 오브젝트를 받았을 때
  • 다음 run loop사이클에 action 메세지를 보냄

case changed

  • GestureRecognizer가 연속적인 제스처로 변함을 인식한 터치를 받았을 때
  • 다음 run loop사이클에 action 메세지를 보냄

case ended

  • GestureRecognizer가 연속적인 제스처의 끝을 인식한 터치를 받았을 때
  • 다음 run loop사이클에 action 메세지를 보내고 상태를 .possible로 바꿈

case cancelled

  • GestureRecognizer가 연속적인 제스처의 취소로 발생한 터치를 받았을 때
  • 다음 run loop사이클에 action 메세지를 보내고 상태를 .possible로 바꿈

case failed

  • GestureRecognizer가 제스처로 인식할 수 없는 멀티 터치 시퀀스를 받았을 때
  • 액션 메세지가 보내지지 않고, 상태를 .possible로 바꿈

static var recognized

  • GestureRecognizer가 제스처로 인식한 멀티 터치 시퀀스를 받았을 때
  • 다음 run loop사이클에 action 메세지를 보내고 상태를 .possible로 바꿈

 

예시

override func viewDidLoad() {
    super.viewDidLoad()
    
    let tap = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture))
    yellowView.addGestureRecognizer(tap)
    print(tap.state.description)
    
    let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressGesture))
    longPress.minimumPressDuration = 0.2
    yellowView.addGestureRecognizer(longPress)
    
    let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture))
    yellowView.addGestureRecognizer(pan)
}

처음 state는 possible입니다.

 

기본적으로 tap하게 되면 다음과 같이 프린트됩니다.

handleTapGesture(_:) ended

tap은 began이 나오지 않습니다.

 

longPress의 minimumPressDuration(기본 0.5)을 0.2로 했기 때문에 0.2초 이상 누르고 있다가 손을 떼면 다음과 같이 프린트됩니다.

handleLongPressGesture(_:) began

handleLongPressGesture(_:) changed

handleLongPressGesture(_:) changed

handleLongPressGesture(_:) changed

handleLongPressGesture(_:) ended

이 때는 tap이 나오지 않습니다.

longPress상태에서 좌우로 움직이면 pan은 반응하지 않습니다.

 

 

하지만 길게누르고 움직이는게 아닌 바로 손을 터치후 움직이면 pan이 시작되고 다음과 같이 프린트됩니다.

handlePanGesture(_:) began

handlePanGesture(_:) changed

handlePanGesture(_:) changed

handlePanGesture(_:) changed

handlePanGesture(_:) ended

이 때는 longPress가 발생하지 않습니다.

 

 

만약에 터치를 지속하고 있다가 홈화면으로 가거나, present된 뷰컨을 dismiss하는 등의 행위를 한다면 다음과 같이 프린트 됩니다.

handleLongPressGesture(_:) began

handleLongPressGesture(_:) changed

 

handleLongPressGesture(_:) changed

handleLongPressGesture(_:) changed

handleLongPressGesture(_:) cancelled

 

 

코드 참고

class ViewController: UIViewController {
    
    @IBOutlet weak var yellowView: UIView!
    
override func viewDidLoad() {
    super.viewDidLoad()
    
    let tap = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture))
    yellowView.addGestureRecognizer(tap)
    print(tap.state.description)
    
    let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressGesture))
    longPress.minimumPressDuration = 0.2
    yellowView.addGestureRecognizer(longPress)
    
    let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture))
    yellowView.addGestureRecognizer(pan)
}
    
    @objc func handleTapGesture(_ sender: UIGestureRecognizer) {
        print(#function, sender.state.description)
    }
    
    @objc func handleLongPressGesture(_ sender: UIGestureRecognizer) {
        print(#function, sender.state.description)
    }
    
    @objc func handlePanGesture(_ sender: UIGestureRecognizer) {
        print(#function, sender.state.description)
    }
    
}

extension UIGestureRecognizer.State {
    
    var description: String {
        var stateString = "unknown"
        
        switch self {
        case .possible:
            stateString = "possible"
        case .began:
            stateString = "began"
        case .changed:
            stateString = "changed"
        case .ended:
            stateString = "ended"
        case .cancelled:
            stateString = "cancelled"
        case .failed:
            stateString = "failed"
        @unknown default:
            break
        }
        return stateString
    }
    
}
댓글
공지사항