2012-05-24 33 views
3

使用上的Xcode 4.3.2空应用程序模板,创建一个项目,所以没有参与NIB。谁调整了我的观点? (iOS上)

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 20; 768 1004); layer = <CALayer: 0x182a00>> 

所以viewDidLoadviewDidAppear之间,该视图被调整大小的第一种方法将打印出

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

。调整它的机制是什么?我们可以指望它吗?因为即使马特纽伯格,高度重视的书籍编程iOS,第二版的作者,这样做(如第508页)。

回答

0

默认情况下,autoresizesSubviews属性将导致一个视图显示时,以调整其子视图。

+0

如果我添加了'[[UIApplication的sharedApplication] keyWindow] .autoresizesSubviews = NO;'到viewDidLoad'的'年底,观点依然是调整 –

0

self.view不实际创建,直到它显示在屏幕上。这是懒加载。在调用viewWillAppear之后,帧将被设置。是的,您可以信任这些值,因为它们是根据手机的屏幕和方向进行设置的。

self.view是一个比较特殊的看法,我往往不直接与它的工作,我通常只是添加一个容器子视图,并将其视为主视图。由于调整大小,最好不要将self.view视为静态实体。确保适当设置子视图的自动调整掩码,以便在self.view更改时正确显示它们。

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

UIKit为我们照顾这个实现细节,这是一种奢望,因为那样我们就不必考虑设备特定的更改,只要确保适当地设置子视图的自动调整大小,并且UIKit负责其余部分。

+0

这两个的NSLog行打印出完全一样的东西...... –

3

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

所以是的,viewDidLoad中和viewDidAppear之间,视图得到它的尺寸和边界,这是完全可靠的,并记录在视图控制器文档。

还要注意,每次需要创建视图时都会调用viewDidLoad(如第一次和低内存警告后 - 当需要内存时通常会释放视图 - ),并且viewWillAppear将在每次视图控制器时被调用位于堆栈顶部,其视图即将呈现。

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

+1

似乎正确的...但是,如果一个空的方法'viewWillAppear'被定义为覆盖默认行为,该视图仍然调整大小... –

+0

100多页的ViewController编程指南...你不能说iOS没有很好地记录... –

+0

这就是为什么我建议使用容器视图。直接使用self.view是一种痛苦,就像x一样,y尺寸将始终保持不变,即使显示翻转时也是如此。这是一个特殊的观点,因为操作系统直接对该视图进行更改。如果你使用'bounds'而不是'frame',你应该没有这个问题 –

0

看起来viewControllerview被调整当你做出这个viewController一个rootViewControllerapplication的的window。否则,你必须手动设置它的框架。

我试过这段代码:

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

viewController2viewDidLoadviewDidAppear被称为。

同样有趣的是: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];是罪魁祸首。