[iOS] shake Motion 감지하기

lnnae·2021년 9월 2일
0

카카오톡 메인에서 shake motion으로 QR 스캔 화면을 present하는 것을 구현해 볼 것이다!


ㅋㅋ근데 메소드를 다 제공해주더군

stackoverflow에서 멋진 걸 찾았다. 5년전 글이긴한데 머 어쩌라고...

motionEnded(_:with:)

receiver에게 motion event가 끝났음을 알려준다.

func motionEnded(_ motion: UIEvent.EventSubtype, 
            with event: UIEvent?)

파라미터를 보자

motion

모션의 종류를 나타내는 event-subtype 상수이다. UIEvent.EventSubtype으로 식별됨! 일반적인 모션은 shaking이다.

종류는 꽤나 여러가지

/// extension UIEvent
public enum EventSubtype : Int {        
        // available in iPhone OS 3.0
        case none = 0

        
        // for UIEventTypeMotion, available in iPhone OS 3.0
        case motionShake = 1

        
        // for UIEventTypeRemoteControl, available in iOS 4.0
				// auido, video에 대한 이벤트를 추적한다!
        case remoteControlPlay = 100

        case remoteControlPause = 101
	
        case remoteControlStop = 102

        case remoteControlTogglePlayPause = 103

        case remoteControlNextTrack = 104

        case remoteControlPreviousTrack = 105

	/// audio, video를 통해 거꾸로 탐색하는 것을 종료하는 이벤트 추적
        case remoteControlBeginSeekingBackward = 106

        case remoteControlEndSeekingBackward = 107

        case remoteControlBeginSeekingForward = 108

        case remoteControlEndSeekingForward = 109
    }

event

motion과 관련된 이벤트를 처리하는 객체

참고로 UIKit은 모션 이벤트의 시작, 종료만 responder에게 알린다. 그러니까 중간 shake는 보고하지 않는다는 것..

모션 이벤트는 최초 first responder에게 전달되고, 적절하게. 필요에 따라 responder chain으로 전달된다.

이 메소드의 기본 구현은 responder chain으로 전달된다는 것임.. 네?

아 쫌 이따가 볼게요 진짜로

motionBegan(_:with:)

얘도 물론 모션 이벤트의 시작을 receiver에게 전달하는 메소드입니다.

parameter도 동일하고요.

motionCancelled(_:with:)

얘도 동일. 모션 이벤트가 취소되었을 때 알려드림니다 -ㅅ-.

근데 .. shake motion에서 과연 취소가 발생할 일이..? 있을까나요

아하.. application이 비활성화되거나 모션 이벤트를 처리하는 view가 윈도우에서 제거되었을 때 중단된다고 함!

UIKit은 shaking이 너무 오래 지속되면 이 메소드가 호출된다. 진짜 이 깍깨물고 흔드니까 이 메소드가 호출됨

모션 이벤트를 처리하는 responder는 이 메소드를 구현해야한다.

그래서 구현할 때, 모션 이벤트 처리와 관련된 상태 정보를 모두 clean up 해야한다!

적용

   override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        if event?.subtype == .motionShake {
            coordinator?.presentQrView()
        }
   }
    
    override func motionCancelled(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
				print("motionCancelled")
    }

사용할 ViewController에서 모션을 감지하는 메소드들을 오버라이드 해줬다
나는 coordinator 패턴을 사용했기 때문에, 모션이 발생하면 qrView를 present 해주는 메소드를 호출할 수 있도록 했다.

완전 간단해서 이 세상에 감사했음.

Responder Chain

https://seizze.github.io/assets/img/2019-11-26-iOS%EC%9D%98-Responder%EC%99%80-Responder-Chain-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0/ios-responder-chain-example.png

이벤트는 FirstResponder에서 시작되어 뷰 계층 - window - app 객체에 도달할 때까지 이동함.

하여간 이것에 따르면,

  • UIView

    1. view가 뷰컨의 루트 뷰일때) next responder는 viewController이다.
    2. 아닌 경우) next responder는 뷰의 슈퍼뷰
  • UIViewController

    1. window의 루트 뷰일 때) next responder는 window 객체
    2. present된 경우) next reponder는 presenting viewController (띄워준 뷰컨)
  • UIWindow

    next responder는 UIApplication

  • UIApplication

    next responder는 AppDelegate (조건: UIResponder의 인스턴스이면서, 뷰, 뷰컨 또는 앱 객체가 아닐 때)

아하 👀
그래서 아까 motionBegan(~~) 메소드 시리즈는 기본적으로 responder chain에 따라 전달된다고 했는데, 그래서 만약에 responder가 되는 인스턴스가 이벤트 처리 메소드를 구현해주지 않았을 때 이 responder chain에 따라 상위로 올라가면서 처리가 될 때까지 구질구질하게.. 올라간다는 뜻임

결과물


영상이라 모르겠지만 흔든 거 마즘.
끗 :)

profile
이내임니당 :>

0개의 댓글

관련 채용 정보