谁调整了我的观点? (在iOS上)

时间:2012-05-24 20:16:18

标签: iphone ios ipad uiview uiviewcontroller

在Xcode 4.3.2上使用Empty App模板,创建了一个项目,因此不涉及NIB。

FooViewController.m

-(void) loadView {
    UIView *view = [[UIView alloc] init];
    view.backgroundColor = [UIColor yellowColor];
    self.view = view;                     
}

因此,视图被实例化并分配给self.view。这两种方法:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSLog(@"self.view is %@", self.view);
}

-(void) viewDidAppear:(BOOL)animated {
    NSLog(@"self.view is %@", self.view);
}

第一种方法将打印出来

self.view is <UIView: 0x18e4d0; frame = (0 0; 0 0); layer = <CALayer: 0x182a00>>

而第二个打印出来

self.view is <UIView: 0x18e4d0; frame = (0 20; 768 1004); layer = <CALayer: 0x182a00>>

因此,在viewDidLoadviewDidAppear之间,视图会调整大小。调整大小的机制是什么?我们真的可以指望它吗?因为即使是备受推崇的“编程iOS,第二版”一书的作者Matt Neuburg也是这样做的(如第508页所述)。

4 个答案:

答案 0 :(得分:3)

您必须了解ViewController生命周期。 在viewDidLoad中,将创建视图,但不会设置边界/尺寸。这将在以下步骤中发生。您可以使用viewWillAppear来设置尺寸(大多数人都这样做)。 ViewDidAppear最后发生,你已经有了最终的外观并且动画已经开始了。

所以,在viewDidLoad和viewDidAppear之间,视图获取其维度和边界,它完全可靠,并且还在ViewController文档中进行了记录。

另请注意,每次需要创建视图时都会调用viewDidLoad(如第一次和低内存警告 - 视图通常在需要内存时释放后),并且每次视图控制器都会调用viewWillAppear在堆栈顶部,它的视图即将被渲染。

查看与视图外观相关的文档: http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/RespondingtoDisplay-Notifications/RespondingtoDisplay-Notifications.html#//apple_ref/doc/uid/TP40007457-CH12

答案 1 :(得分:0)

默认情况下,autoresizesSubviews属性会导致视图在显示时调整其子视图的大小。

答案 2 :(得分:0)

在屏幕上显示之前,实际上并未创建self.view。它是懒惰的。调用viewWillAppear后,将设置框架。是的,您可以信任这些值,因为它们是根据手机的屏幕和方向设置的。

self.view是一个相当特殊的视图,我经常不直接使用它,我通常只是添加一个容器子视图并将其视为主视图。由于调整大小,最好不要将self.view视为静态实体。确保正确设置子视图的自动调整蒙版,以便在self.view更改时正确显示它们。

为了进一步回答您的问题,UIKit专门设置了视图的框架,以考虑屏幕的大小,方向,导航栏,状态栏,工具栏等。您无法保证在{{{{{{{ 1}}被召唤,将是相同的。实际上,如果导航栏,方向或其他因素发生变化,self.view将会更改。因此,即使在viewWillAppear之后,您无法保证self.view的静态大小,如果您更改它,它将被适当重置以反映设备的状态。

UIKit为我们处理这个实现细节,这是一种奢侈,因为我们不必考虑设备特定的更改,只需确保子视图的自动调整得到适当设置,UIKit负责其余部分。< / p>

答案 3 :(得分:0)

当您viewController view viewController rootViewController applicationwindow - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; FooViewController *viewController = [[FooViewController alloc] init]; self.window.rootViewController = viewController; [self.window makeKeyAndVisible]; FooViewController *viewController2 = [[FooViewController alloc] init]; [viewController.view addSubview: [viewController2 view]]; return YES; } viewController viewController2 } 即可。否则你必须手动设置它的帧。

我试过这段代码:

viewController

viewDidLoad viewWillLayoutSubviews viewDidLayoutSubviews viewDidAppear 已调整大小,viewController2未调整大小。

另外:对于viewDidLoad,所有这些方法都被调用:

viewDidAppear

viewController viewWillLayoutSubviews- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; FooViewController *viewController = [[FooViewController alloc] init]; NSLog(@"after init: self.view is %@", viewController.view); self.window.rootViewController = viewController; NSLog(@"after setting to rootViewController: self.view is %@", viewController.view); [self.window makeKeyAndVisible]; NSLog(@"after makeKeyAndVisible: self.view is %@", viewController.view); return YES; } 被调用。

同样有趣:viewDidLoad: frame = (0 0; 0 0) after init: frame = (0 0; 0 0) after setting to rootViewController: frame = (0 0; 0 0) after makeKeyAndVisible: frame = (0 20; 320 460) viewWillLayoutSubviews: frame = (0 20; 320 460) viewDidLayoutSubviews: frame = (0 20; 320 460) viewDidAppear: frame = (0 20; 320 460) 在调用[self.window makeKeyAndVisible];之前已调整大小。

编辑:

我认为这值得进一步测试。使用以下代码:

{{1}}

结果是:

{{1}}

所以 {{1}} 是罪魁祸首。