为啥在子视图中添加图层蒙版时需要调用 layoutIfNeeded()?
Posted
技术标签:
【中文标题】为啥在子视图中添加图层蒙版时需要调用 layoutIfNeeded()?【英文标题】:Why do I need to call layoutIfNeeded() when adding a layer mask to a subview?为什么在子视图中添加图层蒙版时需要调用 layoutIfNeeded()? 【发布时间】:2017-02-28 22:34:18 【问题描述】:我的主视图有一个子视图,我使用以下扩展添加了一个掩码:
extension UIView
func addTopRoundCorners()
let bezierPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: [UIRectCorner.topLeft, UIRectCorner.topRight], cornerRadii: CGSize(width: 20, height: 20))
let maskLayer = CAShapeLayer()
maskLayer.path = bezierPath.cgPath
maskLayer.fillColor = UIColor.red.cgColor
self.layer.mask = maskLayer
我注意到此代码对我的子视图的影响只有在我在主视图上调用layoutIfNeeded()
时才会出现在屏幕上,然后再将掩码添加到我的子视图。如果有人能向我解释这是为什么,我将不胜感激?
【问题讨论】:
你在使用自动布局吗? 您对视图生命周期的理解程度如何?通俗地说,您是在告诉操作系统重新绘制所需的内容。 是的,我正在使用自动布局。但是,我通过代码而不是情节提要添加了它们。我也知道在使用自动布局时,您必须调用layoutIfNeeded()
才能使蒙版起作用,但为什么呢? @apineda
我有点眼熟。 @dfd
那我可能不清楚你在问什么。您向视图添加一些东西——一个层、一个子视图、一个滑块变化,等等——并且需要向操作系统发出信号来更新东西。某些更改(很可能是用户交互)会自动触发此更新。但其他人(添加一个子层,取决于你什么时候做)不需要,因此需要一些东西来触发操作系统来刷新东西。听起来你知道这一点。但如果是这样,那你在问什么?希望这是有道理的。
【参考方案1】:
layoutIfNeeded
将计算视图的位置和大小。如果在计算最终位置和大小之前调用addTopRoundCorners()
函数,那么用于创建UIBezierPath
的self.bounds
将是错误的。
自动布局不会自动调整遮罩层的大小,也不会调用addTopRoundCorners
重新创建路径。
【讨论】:
以上是关于为啥在子视图中添加图层蒙版时需要调用 layoutIfNeeded()?的主要内容,如果未能解决你的问题,请参考以下文章
Swift mapview图层蒙版裁剪/移动视图。我究竟做错了什么?