无法更新viewDidLoad中的view.layer.frame?

我想在我的单个视图控制器项目的viewDidLoad方法中执行以下代码:

self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20); 

但它没有给出所需的插图。 然而,其他用户界面的变化,我在同一个方法做工作,例如

 self.view.layer.backgroundColor = [UIColor orangeColor].CGColor; 

上面的代码行工作和背景是改变为橙色,但框架没有。

只有当我把代码行放在viewDidAppear中时,插入才有效。 我想了解这个行为的关键原因是否有人可以解释。 先谢谢你。

viewDidLoad方法为设置您的视图的框架为时尚早,因为其他更改后的框架。

例如,如果这是您的根视图控制器,则UIWindow对象会在将视图添加到自身作为子视图时设置视图的框架。 viewDidLoad方法在loadView返回之后立即运行,之后任何外部对象(如UIWindow )都可以在视图中进行操作。

你可以使用自定义视图(如果你还没有)和覆盖setFrame:在自定义视图类中:

 - (void)setFrame:(CGRect)frame { [super setFrame:frame]; } 

在该方法中放置一个断点,您将看到在viewDidLoad返回后,视图的框架会被设置一段时间。

我认为你遇到了这个问题:

 self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20); 

可以这样解释:

  • 在viewDidLoad中,属性被设置,但视图的框架尚未定义。
  • 当viewWillAppear被触发时,它们将被设置。 这就解释了为什么这一行代码在那里工作。
  • 但是从iOS 5开始,在viewDidLoad之后调用另一个方法,并且在ViewWillAppear之前设置了视图框架: viewDidLayoutSubviews

你可以在本季的斯坦福大学CS193P课程中find关于iOS编程的完整说明(非常酷)。

所以,如果你想要它只工作一次,使用:

 - (void)viewDidLayoutSubviews { self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20); } 

PS:我也在Ray的论坛上发布了这个答案。 问候,弗雷德

Rob Mayoff的回答是正确和优秀的,但是稍微有些不同: viewDidLoad只意味着视图已经加载,即视图控制器已经获得了视图。 这并不意味着视图已经放置在界面中。 事实上,这是viewDidAppear:意思之一viewDidAppear:这意味着 – 这就是为什么当你在那里运行你的代码时它工作的原因。

在这种情况下,你想初始化一些关于视图的东西的诀窍就是做得太晚,但是只做一次。 viewDidAppear:稍后可以很容易地调用,但是你不想再次初始化视图(除非它已经被卸载)。 在iOS 5中, isMovingToParentViewController允许你区分你正在寻找的特定情况。 在此之前,可能需要设置一个BOOL标志,以便只执行一次最终的初始化。

一个相关的陷阱是什么时候应用程序启动到横向方向。 在这里, viewDidLoad也太快了,因为界面还没有旋转到横向。

但是,这个问题根本不应该出现。 插入视图控制器的视图应该不是你的事。 视图是根视图控制器,在这种情况下,它的大小被自动正确地处理,或者它是父视图控制器的子视图,在这种情况下,它是父视图控制器的视图大小(如UINavigationController,例如,已经做了),或者视图将以模态方式呈现,在这种情况下,其大小将被自动设置以匹配它replace的视图。 所以我build议你非常疑问,表明你做错了什么。

使用旧版本的Xcode创build项目(例如,我使用的是Xcode 4.3.3)。 然后,您可以在任何版本的Xcode中使用setFrame:方法与viewDidLoad。

Ray Wenderlich教程“CALayers简介”也遇到过这个问题。 http://www.raywenderlich.com/2502/introduction-to-calayers-tutorial

看来整个视图控制器视图缩小似乎不是最好的事情。 相反,创build一个子视图,并调用CGRectInset,例如在您的视图控制器viewDidLoad

 UIView *viewToManipulate = [[UIView alloc] initWithFrame:CGRectMake(0.0,0.0, self.view.bounds.size.width, self.view.bounds.size.height)]; [self.view addSubview:viewToManipulate]; viewToManipulate.backgroundColor = [UIColor redColor]; viewToManipulate.layer.cornerRadius = 20.0; viewToManipulate.layer.frame = CGRectInset(self.view.layer.frame, 20, 20);