我有一个简单的UINavigationController。在init方法中,我创建并添加UITableView作为子视图。
- (id)init {
self = [super init];
if (self) {
NSLog(@"%@", NSStringFromCGRect(self.view.frame)); // {{0, 20}, {320, 460}}
tableView = [[UITableView alloc] initWithFrame:self.view.frame];
[self.view addSubview:tableView];
}
return self;
}
我发现在处理新项目时我总是遇到同样恼人的问题。添加的子视图最终位于导航栏下方20个像素处。
为什么我最终以{{0,20},{320,460}}为self.view.frame?我不想强制使用CGRect框架,我宁愿根据视图控制器的框架设置它,所以我不会遇到动态框架更改的问题(网络,电话等状态栏更高的问题)
更新:还注意到我的帧高达460。这也没有意义。在我的情况下,我实际上有一个标签栏,所以高度不应该减去状态栏,减去uinavigationbar并减去标签栏的高度?
由于
答案 0 :(得分:7)
只有在调用-viewWillAppear
,-viewDidAppear
方法时,UIView的框架才会获取有效参数。您不应该依赖框架并在之前使用它进行任何计算
此外,在调用view
方法之前,不应使用(来自其他对象)UIViewController(UItableViewController)的-viewDidLoad
属性,因此不应使用视图并在init
方法中向其添加任何控制器,仅在-loadView
或-viewDidLoad
中(更好)。在这些方法中添加子视图并在出现之前设置其框架
在viewController的生命周期视图中可以多次加载和卸载(例如didReceiveMemoryWarning卸载视图),视图永远不会加载。
答案 1 :(得分:2)
您正在混合两种不同的坐标系。 self.view的框架在窗口的坐标系中定义(或者它的父视图是什么)。 tableView的框架在self.view的坐标系中定义。
如果您想要填充整个视图,请设置
subView.frame = parentView.bounds;
bounds在视图自己的坐标系中定义。 frame在其父视图的坐标系中定义。所以subView.frame和parentView.bounds是相同的坐标系。
当您设置subview.frame = parentView.frame
时,它们最终不会超过20克= 20盎司。主视图起源于(0,20);子视图的起源为(0,20),但是在不同的坐标系中。在窗口坐标系中(0,40)。