UIAlertController is moved to buggy position at top of screen when it calls `presentViewController:`

Originator:peter.kamb
Number:rdar://19037589 Date Originated:19-Nov-2014
Status:Closed Resolved:
Product:iOS Product Version:iOS 8.1
Classification:UI/Usability Reproducible:Always
 
Summary:
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, as seen below. Simply implement viewDidAppear: on the View Controller in a new Single View Xcode project and insert the following.

Sample Xcode Project attached.

Steps to Reproduce:
1. Present a UIAlertController alert.
2. Present a view from the alert
3. Dismiss the view.
4. The UIAlert has now moved to a buggy position at the top of the screen.

Better formatting here:
http://stackoverflow.com/questions/27028983/uialertcontroller-is-moved-to-buggy-position-at-top-of-screen-when-it-calls-pre

Add the following code to `viewDidAppear:` on the View Controller in a new Single View Xcode project and insert the following.

- (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];

    // 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
}

Expected Results:
UIAlertController stays in normal position in center of screen.

Actual Results:
UIAlertController is moved to buggy position at top of screen.

Version:
ios 8.1

Notes:


Configuration:
iOS 8.1 on iPad/iPhone Simulator and iPhone 6 hardware.

Attachments:
'alert.png', 'alert_moved.png', 'alert_end_end.png' and 'UIAlertControllerTest.zip' were successfully uploaded.

Comments

Apple Developer Relations25-Feb-2015 10:52 AM

There are no plans to address this based on the following:

This isn't supported, please avoid presenting on a UIAlertController.

We are now closing this report.

If you have questions about the resolution, or if this is still a critical issue for you, then please update your bug report with that information.

Please be sure to regularly check new Apple releases for any updates that might affect this issue.

By peter.kamb at Feb. 25, 2015, 10:57 p.m. (reply...)

Try this, seems to be the changes in iOS8 around presentation styles and UIAlertController

Create a custom ViewController inheriting from UIViewController and implement UIPopoverPresentationControllerDelegate.

Step 1:

@interface CustomUIViewController : UIViewController<UITextFieldDelegate, UIPopoverPresentationControllerDelegate> ...

Step 2: Present the view in fullscreen but make use of presentation popover

CustomUIViewController *viewController = [[CustomUIViewController alloc] init];
viewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
UIPopoverPresentationController *popController = viewController.popoverPresentationController;
popController.delegate = viewController;
viewController.view.backgroundColor = self.view.tintColor;
[alert presentViewController:viewController animated:YES completion:^{
    dispatch_after(0, dispatch_get_main_queue(), ^{
        [viewController dismissViewControllerAnimated:YES completion:nil];
    });
}];

I had a similar problem where in a Passcode view needs to be displayed on top of any controller, above code help me in solving this problem. Noteworthy change in iOS8 is that UIAlertController inherits from UIViewController which was not the case in UIAlertView

Somehow I don't have enough reputation to post answers on Stackoverflow.


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!