Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

motionBegan:withEvent: not called in AppDelegate in iOS 10

I used to detect a shake motion from the AppDelegate by simply implementing this method:

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

which works fine in iOS 8 and 9. However it doesn't work in iOS 10 anymore. I also tried adding

- (BOOL)canBecomeFirstResponder {
        return YES;
}

but that didn't help. This works fine in the UIViewControllers though. Did something change in iOS 10, or is it just a bug?

like image 370
almas Avatar asked Sep 15 '16 19:09

almas


2 Answers

I had the same issue as you. Instead of implementing it on AppDelegate, I now use UIWindow, which works for me in iOS 8-10. Perhaps this is do-able for you as well?

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 do it even cleaner, you might be able to set a specialized version of the UIWindow on the application.

like image 109
jayjunck Avatar answered Sep 27 '22 22:09

jayjunck


I had a similar issue and I tried @jayjunck's answer but Xcode thrown Method does not override any method from its superclass. I fixed it by replacing public with open to access and override motionBegan function In Swift 3,

  • An open class is accessible and subclassable outside of the defining module. An open class member is accessible and overridable outside of the defining module.

  • A public class is accessible but not subclassable outside of the defining module. A public class member is accessible but not overridable outside of the defining module.

enter 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
        }
}
like image 37
Matt Avatar answered Sep 27 '22 22:09

Matt