我正在尝试在单视图控制器项目的viewDidLoad方法中执行以下代码:
self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20);
但它没有给出理想的插图。但是,我在同一方法中进行的其他UI更改也可以正常工作,例如
self.view.layer.backgroundColor = [UIColor orangeColor].CGColor;
上面的代码行确实有效,背景变为橙色,但框架没有。
只有在viewDidAppear中放置代码行时,插图才有效。如果有人能解释的话,我想了解这种行为的关键原因。提前谢谢。
答案 0 :(得分:19)
我认为你遇到的问题是:
self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20);
可以这样解释:
你可以在本季的斯坦福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
中创建一个子视图并调用CGRectInsetUIView *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);