将子视图添加到自定义视图最终会出错,因为自动布局没有计算尺寸



我创建了一个自定义视图类。我有一个想要模糊的图像视图。我在下面的代码中添加了模糊效果,但显然不起作用,因为图像视图的边界是错误的。由于自动布局尚未计算出图像视图的高度和宽度的正确大小。但是,我应该覆盖哪种方法来访问正确的位置和大小属性?

只添加一次的解决方案是什么?

class ProductListingCell: UICollectionViewCell {
    @IBOutlet weak var nameLabel: UILabel!    
    @IBOutlet weak var sharpImageView: UIImageView!
    @IBOutlet weak var blurImageView: UIImageView!
    override func awakeFromNib() {
        super.awakeFromNib()

        let blurEffect = UIBlurEffect(style: .Light)
        let visualEffectView = UIVisualEffectView(effect: blurEffect)
        visualEffectView.frame = blurImageView.bounds
        blurImageView.addSubview(visualEffectView)
    }
}

(编辑)也许答案是:

发布问题后,我发现了这种方法。这是正确的做法吗?

override func layoutSubviews() {
    super.layoutSubviews()
    layoutIfNeeded()
    let blurEffect = UIBlurEffect(style: .Light)
    let visualEffectView = UIVisualEffectView(effect: blurEffect)
    visualEffectView.frame = blurImageView.bounds
    blurImageView.addSubview(visualEffectView)
}

是的,你是正确的:layoutSubviews()是前进的道路。

但是,您不需要也不应该在layoutSubviews()主体中使用layoutIfNeeded()。这是因为layoutIfNeeded()所做的是检查是否在视图上设置了特定的内部标志(每当您或系统调用setNeedsLayout()时都会设置该标志),如果是这样,它会在视图上调用layoutSubviews()(与您调用它的方法完全相同)。换句话说:如果在调用layoutIfNeeded()之前在layoutSubviews()方法中执行任何使当前布局无效的操作,则可能会在此处创建一个永不结束的递归循环

我在一个示例项目中测试了使用和不使用layoutIfNeeded()调用的代码,两种实现都产生了相同(正确)的结果。请检查您是否对代码进行了任何其他更改。

在自定义视图上调用layoutSubviews()时,可以确保系统在解决了将视图约束为其同级视图及其超视图的所有布局约束后,已经设置了视图的框架。但是,您需要首先调用super.layoutSubviews(),以便正确定位视图的所有子视图。

最新更新