简体   繁体   中英

How can I handle support for shaking the ios device from my swift app?

I'm writing an ios swift app and I want to include a support for shaking the device. As for now I want to print a msg to the console when user shakes his phone. I found this tutorial http://www.ioscreator.com/tutorials/detect-shake-gesture-ios8-swift and it looks super easy, however there's one thing that bothers me.

I want it to work from any view in the app, not only a single one. So no matter where user currently is in the app - he should be able to invoke the shake method. Should I implement the method override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent) { in every panel then? Or is there a way of implementing it once and populating it across the whole app?

First of all lets find out where these 'motion' methods come from, as docs say:

The UIResponder class defines an interface for objects that respond to and handle events. It is the superclass of UIApplication, UIView and its subclasses.. ( https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIResponder_Class/ )

The event-handling methods for motion events are:

func motionBegan(motion: UIEventSubtype, withEvent event: UIEvent?)
func motionCancelled(motion: UIEventSubtype, withEvent event: UIEvent?)
func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent?)

So, as you see, to 'catch' motion events on every screen of the app - we should override these methods in these screens. Thanks God, with extensions - we can make it much easier :)

To incapculate 'motion' logic lets make a protocol and name it 'MotionDelegate':

protocol MotionDelegate {
func motionBegan(motion: UIEventSubtype, withEvent event: UIEvent?)
func motionCancelled(motion: UIEventSubtype, withEvent event: UIEvent?)
func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent?)

}

And make an extension of UIViewController, conforming MotionDelegate protocol:

extension UIViewController:MotionDelegate {
override public func becomeFirstResponder() -> Bool {
    return true
}

override public func motionBegan(motion: UIEventSubtype, withEvent event: UIEvent?) {
    if motion == .MotionShake { print("Shaking motionBegan with event\(event)") }
}

override public func motionCancelled(motion: UIEventSubtype, withEvent event: UIEvent?) {
    if motion == .MotionShake { print("Shaking motionCancelled with event\(event)") }
}

override public func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent?) {
    if motion == .MotionShake { print("Shaking motionEnded with event\(event)") }
}

}

In this way motion handling will be working on EVERY UIViewController instances of your appliction.

To handle motion event on some certain vc your should override it in its extension:

extension MotionViewController {
override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent?) {
    if motion == .MotionShake {
        print("MotionViewController Shaking motionEnded with event\(event)")
    }
}

}

Hope it helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM