Problem after dismissing a modal view used in conjunction with a uisplitviewcontroller

孤街醉人 提交于 2019-12-06 16:28:48

I've had exactly the same problem (#4, above). I worked around it using viewDidAppear:animated, and then checking the height of the view to see if it is in landscape vs. portrait. (Yuck, gag, etc.) I'm not satisfied at all with that "solution".

Possibly related: I've noticed that the button in portrait mode is slow to disappear after rotating to landscape, i.e. the button appears for a second after the rotation finishes. However, in Mail.app, the "Inbox" button disappears as soon as the rotation starts. Is Apple doing things differently than they recommend in their docs? Perhaps there is a more efficient way to show/hide the master view button?

Unfortunately this is not a bug. It appears to be an expected behavior.

I found this in iOS Release Notes for iOS 5.0, in "Notes and Known Issues" section:

Rotation callbacks in iOS 5 are not applied to view controllers that are presented over a full screen. What this means is that if your code presents a view controller over another view controller, and then the user subsequently rotates the device to a different orientation, upon dismissal, the underlying controller (i.e. presenting controller) will not receive any rotation callbacks. Note however that the presenting controller will receive a viewWillLayoutSubviews call when it is redisplayed, and the interfaceOrientation property can be queried from this method and used to lay out the controller correctly.

For diagnostics, have you tried dismissing the popover view first? Or logging who is calling the method by printing (id) sender?

I was having the same exact problem.

In answer to (2), it appears to be a bug. I noticed that when a modal view is pushed over a splitview, the orientation messages are queued up somewhere and not processed until the modal view is dismissed and the splitview is visible but I would still expect to only get one callback.

For (4), this too appears to be a bug. Fortunately, the didRotate... events still get through, so my solution was to subclass UISplitViewController and explicitly call the delegate's willShowViewController method in this case:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

    //Work around a bug where UISplitViewController does not send 
    //willShowViewController after a modal is presented in portrait
    //but dismissed in landscape.
    UIInterfaceOrientation orientation = self.interfaceOrientation;
    if ( (orientation == UIInterfaceOrientationLandscapeLeft )
        || (orientation == UIInterfaceOrientationLandscapeRight) )
    {
        UINavigationItem* item = [detail.navigationBar.items objectAtIndex:0];
        UIBarButtonItem* barButtonItem = [item leftBarButtonItem];
        [super.delegate splitViewController:self willShowViewController:master invalidatingBarButtonItem:barButtonItem];
    }
}

Here, "master" is an IBOutlet that refers to the master view controller (left hand side) of the splitview and "detail" is an IBOutlet for the detail view controller (right hand size).

Note that in my case, the detail view is a UINavigationController. You may require different code to get the barButtonItem from your view controller.

Also, this has the side-effect of calling willShowViewController twice for normal rotation, but that is not an issue in my case.

CodeSpyder

I think that this is a bug that needs to be reported to Apple Development.

I worked around part of this issue by presenting my modal view using the UIModalPresentationPageSheet format.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!