I found that the keyboard touches the hitTest trigger, if I show the keyboard, send the application to the background and come back. This should not happen, so it seems like an iOS bug. I see two solutions:
# 1 Send a message
Solution # 1: hitTest should not be caused by touching the keyboard, so check on the keyboard frame and release the sensor.
var keyboardFrame: CGRect? override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if let keyboardFrame = keyboardFrame { if keyboardFrame.contains(point){ return super.hitTest(CGPoint(x:-1,y:-1), with: event) } } return super.hitTest(point, with: event) } deinit { NotificationCenter.default.removeObserver(self) } func subscribeKeyboard(){ NotificationCenter.default.addObserver(self, selector: #selector(MyView.keyboardDidShow(_:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(MyView.keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil) } func keyboardDidShow(_ notification: NSNotification) { keyboardFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue } func keyboardWillHide(_ notification: NSNotification) { keyboardFrame = nil }
# 2 Pull the keyboard before resigning
Solution 2 #: Before canceling activation, pull the keyboard. Two flaws: you touch the delegate to fix something else, and the user is surprised to find the keyboard when the application returns.
func applicationWillResignActive(_ application: UIApplication) { UIApplication.shared.sendAction(#selector(self.resignFirstResponder), to: nil, from: nil, for: nil) }
Or if you want this to be done only for a specific controller of the form:
if let controller = UIApplication.shared.keyWindow?.topmostViewController { if controller is MyViewController { NSLog("Pulling the keyboard to prevent touches from falling through after coming back from the background.") UIApplication.shared.sendAction(#selector(self.resignFirstResponder), to: nil, from: nil, for: nil) } }
where topmostViewController:
extension UIViewController { static var topmostViewController: UIViewController? { return UIApplication.shared.keyWindow?.topmostViewController } var topmostViewController: UIViewController? { return presentedViewController?.topmostViewController ?? self } } extension UINavigationController { override var topmostViewController: UIViewController? { return visibleViewController?.topmostViewController } } extension UITabBarController { override var topmostViewController: UIViewController? { return selectedViewController?.topmostViewController } } extension UIWindow { var topmostViewController: UIViewController? { return rootViewController?.topmostViewController } }
Leonardo Cardozo wrote the extensions above.