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

时间:2012-02-28 04:07:45

标签: ios uiview uiviewcontroller

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

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

但它没有给出理想的插图。但是,我在同一方法中进行的其他UI更改也可以正常工作,例如

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

上面的代码行确实有效,背景变为橙色,但框架没有。

只有在viewDidAppear中放置代码行时,插图才有效。如果有人能解释的话,我想了解这种行为的关键原因。提前谢谢。

5 个答案:

答案 0 :(得分:19)

我认为你遇到的问题是:

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

可以这样解释:

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

你可以在本季的斯坦福CS193P课程中找到关于iOS编程的完整解释(顺便说一下非常酷)。

因此,如果您希望它只使用一次,请使用:

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

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

答案 1 :(得分:14)

viewDidLoad方法设置视图的框架为时尚早,因为其他内容会在以后更改框架。

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

您可以使用自定义视图(如果您尚未使用)并在自定义视图类中覆盖setFrame:来对此进行测试:

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

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

答案 2 :(得分:5)

Rob Mayoff的答案是正确和优秀的,但是它的方式略有不同:viewDidLoad仅表示视图已加载,即视图控制器已获取其视图。这并不意味着视图已放置在界面中。确实,这是viewDidAppear:的意思之一 - 这就是为什么当你在那里运行代码时它起作用的原因。

在这种情况下,你想要初始化关于视图的东西的诀窍是要做得足够晚但只做一次。稍后可以轻松再次调用viewDidAppear:,但您不希望再次初始化视图(除非已将其卸载)。在iOS 5中,isMovingToParentViewController允许您区分您正在寻找的特定环境。在此之前,可能需要设置BOOL标志,以便只执行一次最终初始化。

当应用程序启动到横向时会发生相关陷阱。在这里,viewDidLoad太快了,因为界面还没有旋转到横向。

然而,这个问题根本不应该出现。嵌入视图控制器的视图应该是您的业务。视图是根视图控制器,在这种情况下,它的大小是自动正确处理的,或者它是父视图控制器的子节点,在这种情况下,它是父视图控制器调整视图大小的工作(如UINavigationController,例如,已经这样做了,或者视图是以模态方式呈现的,在这种情况下,它的大小将自动设置以匹配它所替换的视图。因此,我建议你提出一个问题,表明你做错了什么。

答案 3 :(得分:2)

使用较旧版本的Xcode创建项目(例如我正在使用Xcode 4.3.3)。然后你可以在任何版本的Xcode中使用setFid:方法和viewDidLoad。

答案 4 :(得分:0)

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

似乎缩小了整个视图控制器视图并不是最好的事情。而是在视图控制器viewDidLoad

中创建一个子视图并调用CGRectInset
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);