present一个xib controller产生frame错误的问题

最近写项目时,发现了一个问题:

使用presentViewController方法present到一个包含childViewControllers的containerController时,containerController的childViewConroller是一个xib创建的viewControllerA,present之后,ViewControllerA的frame等于ViewControllerA的xib尺寸,而不是屏幕大小(比如,ViewControllerA的xib尺寸是375x667,在7 Plus上展示的时候,得到的ViewControllerA仍然是375x667);而同样是作为childViewController的ViewControllerB用纯代码创建,则能够按照屏幕尺寸正确展示。

解决方法:

在xib创建的childViewController的viewDidLoad方法中重置该Controllerframe

1
2
3
UIWindow *window = [UIApplication sharedApplication].keyWindow;
self.view.frame = window.frame;
[self.view setNeedsLayout];
demo
  1. demo地址:https://github.com/zhengry/PresentTest

  2. demo说明:

    在414x736尺寸屏幕上测试(xib尺寸和测试屏幕大小不同就可以),

    FirstChildViewController使用375x667尺寸的xib创建,SecondChildViewController使用320x480尺寸的xib创建,ThirdChildViewController使用纯代码创建。

    在containerController中添加childViewController:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    FirstChildViewController *first = [[FirstChildViewController alloc] initWithNibName:@"FirstChildViewController" bundle:nil];

    SecondChildViewController *second = [[SecondChildViewController alloc] initWithNibName:@"SecondChildViewController" bundle:nil];

    ThirdChildViewController *third = [[ThirdChildViewController alloc] init];

    [self addChildViewController:first];
    [self addChildViewController:second];
    [self addChildViewController:third];

    给每个子Controller添加了tap手势,可以点击切换不同的Controller查看展示出来的Controller大小。

    在ViewController中present到containerController:

    1
    2
    ContainerViewController *container = [[ContainerViewController alloc] init];
    [self presentViewController:container animated:YES completion:nil];

    在没有重置frame时,presentViewController之后,FirstChildViewController的view尺寸是(375,667);SecondChildViewController的view尺寸是(320,480),只有ThirdChildViewController是按7 Plus屏幕大小正确呈现。

    在两个xib创建的子controller的viewDidLoad方法添加如下代码,重置子controller的frame:

    1
    2
    3
    4
    5
    NSLog(@"重置前firstChildController--%@",self.view);
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    self.view.frame = window.frame;
    [self.view setNeedsLayout];
    NSLog(@"重置后firstChildController--%@",self.view);
    1
    2
    3
    4
    5
    NSLog(@"重置前secondChildController--%@",self.view);
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    self.view.frame = window.frame;
    [self.view setNeedsLayout];
    NSLog(@"重置后secondChildController--%@",self.view);

    在ThirdChildViewController的viewDidLoad方法里直接打印self.view。

    得到的打印结果:

    childViewController

    可以看出,用xib创建的子controller的frame被重置后,都能够按照屏幕尺寸正确展示。