【问题标题】:Figuring out initWithFrame:self.view.frame 20 pixel (status bar) issue once and for all一劳永逸地解决 initWithFrame:self.view.frame 20 像素(状态栏)问题
【发布时间】:2011-11-11 20:52:26
【问题描述】:

我有一个简单的 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 像素处。

为什么我的 self.view.frame 以 {{0, 20}, {320, 460}} 结束?我不想强制使用 CGRect 框架,我宁愿根据视图控制器的框架设置它,这样我就不会遇到动态框架更改的问题(状态栏较高的网络共享、电话等) .

更新:还注意到我的框架高度为 460。这也没有道理。就我而言,我实际上有一个标签栏,所以高度不应该减去状态栏,减去 uinavigationbar 并减去标签栏高度?

谢谢

【问题讨论】:

  • 因为状态栏20像素高度

标签: ios uiviewcontroller frame


【解决方案1】:

只有在调用-viewWillAppear-viewDidAppear 方法时,UIView 的框架才采用有效参数。您不应该依赖框架并在之前使用它进行任何计算。
此外,在调用-viewDidLoad 方法之前,您不应使用(来自其他对象)UIViewController (UItableViewController) 的view 属性,因此您不应在init 方法中使用视图并向其添加任何控制器,仅在-loadView 中或(更好)-viewDidLoad。在这些方法中添加您的子视图并在出现之前设置其框架。
在 viewController 的生命周期中,视图可以多次加载和卸载(例如 didReceiveMemoryWarning 卸载视图),视图永远无法加载。

【讨论】:

    【解决方案2】:

    您正在混合两个不同的坐标系。 self.view 的框架是在窗口的坐标系中定义的(或者它的父视图是什么)。 tableView 的 frame 是在 self.view 的坐标系中定义的。

    如果你想让某些东西填满整个视图,请设置

    subView.frame = parentView.bounds;
    

    bounds 在视图自己的坐标系中定义。 frame 在其父视图的坐标系中定义。所以 subView.frame 和 parentView.bounds 是同一个坐标系。

    当您设置subview.frame = parentView.frame 时,它们最终不会超过 20 克 = 20 盎司。主视图的原点位于 (0, 20);子视图的原点位于 (0, 20),但在不同的坐标系中。在 (0, 40) 的窗口坐标系中。

    【讨论】:

    • 好的,谢谢。事实上,这就是它在 Apple 的 iOS 开发文档中的记录方式:UIView 类参考 > 属性 > “边界”和“框架”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-25
    • 2016-07-20
    • 2017-06-16
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多