I have an inputAccessoryView for a chat app that always remains visible and docked at the bottom of the screen for text input similar to most messaging apps.
When I present an alertController with actionSheet style, the inputAccessoryView animates down off screen as the alert is presented and then back up again when the alert is dismissed. This in turn scrolls my tableView and is undesirable.
This is happening because the chat viewController is giving up firstResponder when the alert is presented.
Is there anyway to present an alertController and not give up firstResponder, or anyway to keep an inputAccessoryView docked at the bottom of the screen when it's view resignsFirstResponder?
The
InputAccessoryView
sits outside of your ViewController's hierarchy - it's contained in theUITextEffectsWindow
whose rootViewController is aUIInputWindowController
. Similarly the keyboard is contained inUIRemoteKeyboardWindow
and its ownUIInputWindowController
.So, if we present the alert from the topmost window or higher (
UITextEffectsWindow
orUIRemoteKeyboardWindow
), it won't resign first responder.The simplest solution I've found is:
let topViewController = UIApplication.shared.windows.last!.rootViewController!
topViewController.present(alert, animated: true, completion: nil)
Ideally you would safely handle those optionals. A potentially better solution (I've seen some console errors from the previous solution) would be to create a new UIWindow with a higher WindowLevel, make it the key window and visible, and present the alert from there.
For those looking the Objective-C equivalent of Corey's answer: