改变UIView的CALayer框架(self.view.layer.frame = ...)似乎没有任何效果。

6
我相信我错过了一些基本的东西。我正在尝试运行CALayers的'hello world'代码,来自以下网址:http://www.raywenderlich.com/2502/introduction-to-calayers-tutorial
这是第一个例子。在Xcode 4.2中新建单个视图项目,不需要更改nib/storyboard。导入QuartzCore。将以下代码添加到ViewController.m的ViewDidLoad函数中。
- (void)viewDidLoad
{
    [super viewDidLoad];

    self.view.layer.backgroundColor = [UIColor blueColor].CGColor;
    self.view.layer.cornerRadius = 30.0;    
    self.view.layer.frame = CGRectMake(20, 20, 20, 20);
}

我运行(iPad 2或iPad模拟器)并获得一个带有圆角的全屏蓝色矩形。我原本希望得到一个20x20的蓝色矩形,偏移量为20/20。
显然,我已经掌控了views层(颜色和圆角都显示出来了)。但是,调整frame似乎没有影响。我已经NSLog过设置前/设置后的frame,发现它已经改变了。根层的frame是否被锁定在UIview frame上?
我没有强烈的理由去更改views层的frame,我只是试图推理一下发生了什么。希望这是一个简单的问题...
谢谢!
保罗
2个回答

11

实际上,之前的回答(你无法设置uiview.layer.frame,因为它总是填充uiview)接近,但不完整。在阅读答案后,我注册了原始网站并评论称教程有问题。在此过程中,我发现已经有评论处理了这个问题,但我第一次浏览时没有看到。使用那些评论,我开始做一些测试。

结论是,如果您将self.view.layer.frame设置代码从viewDidLoad移动到viewWillAppear,它可以正常工作。这意味着您可以更改视图的根层的框架。但是,如果您在viewDidLoad中执行此操作,稍后会被撤消。

然而,之前的答案仍然很接近。我打印了根层和视图帧的框架。更改根层框架会更改视图框架。因此,视图层框架始终填充视图框架的答案是正确的。但是,设置层框架会重置视图框架以匹配。(我猜uiview.frame属性只返回uiview.layer.frame...)

因此,在2010年至今的某个时间点,环境中的某些东西发生了变化。特别是,在viewDidLoad之后和viewWillAppear之前,uiview/layer框架似乎被重置为nib指定的值。这将覆盖viewDidLoad中的任何更改。在viewWillAppear中进行的更改似乎会保持不变。

Robin的答案让我找对了方向,但我想详细说明全面的答案。


9

这篇教程有误。设置视图主层的框架没有效果。主层是“特殊”的,它将始终填充视图的边界。你需要做的是创建主层的子层,像这样:

- (void)viewDidLoad
{
    [super viewDidLoad];

    CALayer *newLayer = [[CALayer alloc] init];

    newLayer.backgroundColor = [UIColor orangeColor].CGColor;
    newLayer.cornerRadius = 20.0;
    newLayer.frame = CGRectMake(100.0f, 100.0f, 200.0f, 200.0f);

    [self.view.layer addSublayer:newLayer];

    [newLayer release]; // Assuming you're not using ARC
}

此外,您的代码中一个宽度为20pt和高度为20pt的图层无论如何都太小了,不足以具有30pt的圆角。


非常感谢!这正是我怀疑的。创建/操作子图层我没问题。我只是想确保我没有漏掉什么。 - pmeyer
1
实际上,这不是全部。我现在还不能自我回答(声望不够),但稍后我会给出完整的回答。现在来说:如果你在viewDidLoad中改变了view.layer.frame,那么它会在viewWillAppear之前被覆盖(从nib?)。如果你在viewWillAppear中改变view.layer.frame,它就能正常工作并缩小layer。但是,它也会改变uiview.frame。我的猜想是uiview.frame只是返回uiview.layer.frame的属性。 - pmeyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接