在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>>
因此,在viewDidLoad
和viewDidAppear
之间,视图会调整大小。调整大小的机制是什么?我们真的可以指望它吗?因为即使是备受推崇的“编程iOS,第二版”一书的作者Matt Neuburg也是这样做的(如第508页所述)。
答案 0 :(得分:3)
您必须了解ViewController生命周期。 在viewDidLoad中,将创建视图,但不会设置边界/尺寸。这将在以下步骤中发生。您可以使用viewWillAppear来设置尺寸(大多数人都这样做)。 ViewDidAppear最后发生,你已经有了最终的外观并且动画已经开始了。
所以,在viewDidLoad和viewDidAppear之间,视图获取其维度和边界,它完全可靠,并且还在ViewController文档中进行了记录。
另请注意,每次需要创建视图时都会调用viewDidLoad(如第一次和低内存警告 - 视图通常在需要内存时释放后),并且每次视图控制器都会调用viewWillAppear在堆栈顶部,它的视图即将被渲染。
答案 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
application
时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
已调整大小,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}} 是罪魁祸首。