iOS 8: Presenting a modal view controller in portrait causes resize of the navigation bar of the underlying landscape navigation controller

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-20 12:43:24

问题


On iOS 8 I have a strange behavior regarding the navigation bar and orientation changes.

I have a navigation controller which reports a supported interface orientation UIInterfaceOrientationMaskLandscapeRight. The navigation bar has the expected height for landscape orientation (sadly I am not entitled to post screenshots).

Then I initiate a modal presentation of a view controller that only supports UIInterfaceOrientationMaskPortrait. When the presentation animation starts, it seems that the metrics of the underlying navigation controller are changed to a portrait presentation, as the height of the navigation bar grows to its portrait size, as depicted above.

iOS 7 does not exhibit this behavior. What am I missing? I want to restore the old behavior.

Here is the full code of the simple example above:

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];


    DOGButtonViewController *root = [DOGButtonViewController new];
    DOGOrientedNavigationController *navi = [[DOGOrientedNavigationController alloc] initWithRootViewController:root];
    navi.allowedInterfaceOrientations = UIInterfaceOrientationMaskLandscapeRight;

    self.window.rootViewController = navi;

    [self.window makeKeyAndVisible];
    return YES;
}

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortrait;
}

@end


@implementation DOGOrientedNavigationController

- (NSUInteger)supportedInterfaceOrientations
{
    return self.allowedInterfaceOrientations;
}

@end

@implementation DOGButtonViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = @"Button View Controller";
}

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

- (IBAction)buttonClicked:(id)sender
{
    DOGPortraitViewController *vc = [DOGPortraitViewController new];
    [self presentViewController:vc animated:YES completion:nil];
}

@end

@implementation DOGPortraitViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = @"Portrait Title";
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

- (IBAction)buttonClicked:(id)sender
{
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

@end

In a more complex setup I also experience the text in a UIWebView contained in the navigation controller being scaled up when presenting the portrait modal. When dismissing the modal, the text is not resized to its original size.


回答1:


For lack of a better option I've done a bit of a hack for this. Basically before I show the modal view I take a screen shot and lay it on top of the presenting view controller.

Obviously I have to remove this screen shot when the view re-appears

  func showScreenShot () {
    let image = screenShot()
    self.screenShotImageView = UIImageView(image: image)
    self.view.addSubview(self.screenShotImageView!)
  }

func screenShot () -> UIImage {
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, true, UIScreen.mainScreen().scale)
    self.view.layer.renderInContext(UIGraphicsGetCurrentContext())
    let image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image
}

func removeScreenShot () {
  if let screenImageView = self.screenShotImageView {
   screenImageView.removeFromSuperview()
   self.screenShotImageView = nil
  }
}


来源:https://stackoverflow.com/questions/26035020/ios-8-presenting-a-modal-view-controller-in-portrait-causes-resize-of-the-navig

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