Presenting a view from a UIAlertController
moves the alert to a buggy position at the top-left corner of the screen. iOS 8.1, device and simulator.
We have noticed this in an app when we attempt to present a view from the current "top-most" view. If a UIAlertController happens to be the top-most view we get this behavior. We have changed our code to simply ignore UIAlertControllers, but I'm posting this in case others hit the same issue (as I couldn't find anything).
We have isolated this to a simple test project, full code at the bottom of this question.
- Implement
viewDidAppear:
on the View Controller in a new Single View Xcode project. - Present a
UIAlertController
alert. - Alert controller immediately calls
presentViewController:animated:completion:
to display and then dismiss another view controller:
The moment the presentViewController:...
animation begins, the UIAlertController is moved to the top-left corner of the screen:
When the dismissViewControllerAnimated:
animation ends, the alert has been moved even further into the top-left margin of the screen:
Full code:
- (void)viewDidAppear:(BOOL)animated {
// Display a UIAlertController alert
NSString *message = @"This UIAlertController will be moved to the top of the screen if it calls `presentViewController:`";
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"UIAlertController iOS 8.1" message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"I think that's a Bug" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
// The UIAlertController should Present and then Dismiss a view
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = self.view.tintColor;
[alert presentViewController:viewController animated:YES completion:^{
dispatch_after(0, dispatch_get_main_queue(), ^{
[viewController dismissViewControllerAnimated:YES completion:nil];
});
}];
// RESULT:
// UIAlertController has been moved to the top of the screen.
// http://i.imgur.com/KtZobuK.png
}
Is there anything in the above code that would be causing this issue? Do any alternatives exist that would allow bug-free presentation of a view from a UIAlertController?
rdar://19037589
http://openradar.appspot.com/19037589
I was dealing with the same problem with swift, and I fixed it by changing this:
to this:
User
manoj.agg
posted this answer to the Open Radar bug report, but says:Posting his answer here for posterity. I have not tested/evaluated it.
Step 1:
Create a custom View Controller inheriting from
UIViewController
and implementUIPopoverPresentationControllerDelegate
:Step 2:
Present the view in fullscreen, making use of the presentation popover:
I had a similar problem where a password input view needed to be displayed on top of any other View Controller, including UIAlertControllers. The above code helped me in solving the problem. Noteworthy change in iOS 8 is that
UIAlertController
inherits fromUIViewController
, which was not the case forUIAlertView
.rdar://19037589 was closed by Apple
I think that you only should to categorize UIAlertController like this:
In addition to Carl Lindberg's answer There are two cases that also should be taken into account:
So, the full answer that worked for me:
Also, if using category, then you need to store keyboard height somehow, like this: