inputAccessoryView animating down when alertController (actionSheet) presented
Asked Answered
B

4

8

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?

Brickyard answered 29/10, 2017 at 2:17 Comment(2)
It's been several years since I implemented this, but IIRC I just used a text view and moved it based on the keyboard notification, rather than making it an accessory.Detergency
I need to use an inputAccessoryView so that's not an option for meBrickyard
P
13

The InputAccessoryView sits outside of your ViewController's hierarchy - it's contained in the UITextEffectsWindow whose rootViewController is a UIInputWindowController. Similarly the keyboard is contained in UIRemoteKeyboardWindow and its own UIInputWindowController.

So, if we present the alert from the topmost window or higher (UITextEffectsWindow or UIRemoteKeyboardWindow), 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.

Peepul answered 5/4, 2018 at 3:50 Comment(3)
This logs a warning: Keyboard cannot present view controllers (attempted to present <UIAlertController: 0x7fd63004d600>)Khz
@JordanH Yea, these days I'm a fan of creating new windows that get presented over top - this is also useful for "toasts", drop-down banners, etc.Peepul
This doesn't work for full page modal View Controller. For example, when you open Camera app to pick an image, when you come back, the input toolbar would have disappeared.Hunterhunting
M
2

Thanks to @Corey W. (give votes to him) we have a solution for this issue. Safer way in Swift 5:

// Instantiate AlertController
let actionSheet = UIAlertController(title: title,
                                    message: "Comment options",
                                    preferredStyle: .actionSheet)

// Add actions
actionSheet.addAction(UIAlertAction(title: "Edit",
                                    style: .default,
                                    handler: { (_: UIAlertAction) in
                                        self.showEditingView(withCommentId: commentId, withCommentText: commentText)
}))

// Present AlertController
if let lastApplicationWindow = UIApplication.shared.windows.last,
    let rootViewController = lastApplicationWindow.rootViewController {
    rootViewController.present(actionSheet, animated: true, completion: nil)
}
Minoru answered 15/6, 2020 at 11:16 Comment(0)
X
1

For those looking the Objective-C equivalent of Corey's answer:

UIViewController *objViewController = [UIApplication sharedApplication].windows.lastObject.rootViewController;
[objViewController presentViewController:view animated:YES completion:nil];
Xanthene answered 23/9, 2018 at 18:35 Comment(0)
C
1
let rootViewController = UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.windowScene?.windows.last?.rootViewController
rootViewController?.present(createImagePickAlertController(vc: self, pickerController: pickerController), animated: false)

This one works fix "Keyboard cannot present view controllers (attempted to present <UIAlertController: 0x7fd63004d600>)" error.

Chickamauga answered 3/3, 2023 at 10:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.