MotionBegan: withEvent: not called in AppDelegate in iOS 10

I used to detect shake movement from AppDelegate by simply following this method:

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event { NSLog(@"shake shake shake"); } 

which works fine in iOS 8 and 9. However, it no longer works in iOS 10. I also tried adding

 - (BOOL)canBecomeFirstResponder { return YES; } 

but it did not help. However, this works great in UIViewControllers. Has something changed in iOS 10, or is it just a mistake?

+8
ios iphone uikit ios10 uiresponder
source share
3 answers

I had the same problem as you. Instead of embedding it in AppDelegate, I now use UIWindow, which works for me on iOS 8-10. Perhaps this is also useful for you?

 extension UIWindow { override open var canBecomeFirstResponder: Bool { return true } override open func motionBegan(_ motion: UIEventSubtype, with event: UIEvent?) { if motion == .motionShake { //logic here } } } 

If you want to make it even cleaner, you can install a custom version of UIWindow in the application.

+7
source share

I had a similar problem and I tried @jayjunck to answer, but Xcode threw away Method does not override any method from its superclass . I fixed this by replacing public with open to access and cancel the motionBegan function. In Swift 3

  • The open class is accessible and subclassed outside the defining module. The public member of the class is accessible and can be redefined outside the defining module.

  • The public class is accessible, but cannot be subclassed outside the defining module. The public member of the class is accessible, but cannot be redefined outside the defining module.

enter the code here

 extension UIWindow { override open func motionBegan(_ motion: UIEventSubtype, with event: UIEvent?) { super.motionBegan(motion, with: event) guard motion == UIEventSubtype.motionShake else { return } // Shake is detected } } 

Swift 5

 extension UIWindow { open override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) { super.motionBegan(motion, with: event) guard motion == UIEvent.EventSubtype.motionShake else { return } // Shake is detected } } 
+1
source share

You must override the motionBegan method in (all) View Controller (s).

-3
source share

All Articles