更改 UIView 的 CALayer (self.view.layer.frame = ...) 的框架似乎没有效果
Posted
技术标签:
【中文标题】更改 UIView 的 CALayer (self.view.layer.frame = ...) 的框架似乎没有效果【英文标题】:Changing frame of UIView's CALayer (self.view.layer.frame = ...) appears to have no effect 【发布时间】:2011-10-22 14:42:01 【问题描述】:我确定我在这里遗漏了一些基本的东西。我正在尝试来自以下位置的 CALayers 'hello world' 代码:
http://www.raywenderlich.com/2502/introduction-to-calayers-tutorial
做第一个例子。 xcode 4.2 中的新单视图项目。笔尖/故事板没有变化。导入 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 模拟器)并得到一个带圆角的全屏蓝色矩形。我希望得到的是一个偏移 20/20 的 20x20 蓝色矩形。
我显然可以控制视图层(如颜色和圆角所示)。但是,调整框架似乎没有影响。我在设置它之前/之后对框架进行了 NSLog 处理,它已经改变了。根层的框架是否锁定在uiview框架上?
我没有充分的理由来更改视图层框架,我只是想通过正在发生的事情进行推理。希望这是一个简单的问题...
谢谢!
保罗
【问题讨论】:
【参考方案1】:实际上,前面的答案(你不能设置 uiview.layer.frame 因为它总是填满 uiview)很接近,但还不够完整。阅读答案后,我注册了原始站点并评论该教程有问题。在这样做的过程中,我发现已经有一些我在第一次通过时没有看到的 cmets 解决了这个问题。使用这些,我开始做一些测试。
最重要的是,如果将 self.view.layer.frame 设置代码从 viewDidLoad 移动到 viewWillAppear,它可以正常工作。这意味着您可以更改视图根层的框架。但是,如果您在 viewDidLoad 中执行此操作,它将在稍后撤消。
但是,之前的答案仍然非常接近。我 NSLog'ed 根层的框架和视图的框架。更改根层框架会更改视图框架。所以,view.layer.frame 总是填充 view.frame 的答案是正确的。但是,设置图层框架会重置视图框架以匹配。 (我猜 uiview.frame 属性只是返回 uiview.layer.frame...)
因此,在 2010 年到今天之间的某个时间点,环境发生了一些变化。具体来说,在 viewDidLoad 之后和 viewWillAppear 之前,uiview/layer 框架似乎被重置为 nib 指定值。这会覆盖 viewDidLoad 中的任何更改。在 viewWillAppear 中所做的更改似乎保持不变。
Robin 的回答让我走上了正轨,但我想拼出完整的答案。
【讨论】:
【参考方案2】:教程错了。设置视图主层的框架没有效果。主层是“特殊的”,将始终填充视图的边界。您需要做的是像这样创建主层的子层:
- (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 的圆角。
【讨论】:
非常感谢!正是我所怀疑的。创建/操作子层我很好。我只是想确保我没有遗漏任何东西。 实际上,还有更多。我还不能自我回复(没有足够的代表),但我稍后会给出完整的回复。现在:如果您在 viewDidLoad 中更改 view.layer.frame,它会在 viewWillAppear 之前的那一点之后被覆盖(来自 nib?)。如果您更改 viewWillAppear 中的 view.layer.frame,它会起作用并缩小图层。但是,它也会更改 uiview.frame。我的猜测是 uiview.frame 只是一个返回 uiview.layer.frame 的属性。以上是关于更改 UIView 的 CALayer (self.view.layer.frame = ...) 的框架似乎没有效果的主要内容,如果未能解决你的问题,请参考以下文章
将 CALayer 添加到 UIView 并能够在方向更改时重绘
当 UIViewController 显示弹出框时,更改 CALayer 颜色与 UIView tintColor 同步