由于自动布局未计算尺寸,因此将子视图添加到自定义视图会导致错误

时间:2015-12-12 00:30:46

标签: ios swift uiview autolayout

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

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

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)
}

1 个答案:

答案 0 :(得分:2)

是的,你是对的:layoutSubviews()是要走的路。

但是,您不需要且实际上不应在layoutIfNeeded()正文中使用layoutSubviews()。这是因为layoutIfNeeded()所做的是检查视图上是否设置了特定的内部标志(无论何时或系统调用setNeedsLayout()时都设置了该标志),如果是这样,则调用layoutSubviews()在视图上(与您调用它的方法相同)。换句话说:如果您在调用layoutSubviews()之前执行使layoutIfNeeded()方法中的当前布局无效的任何操作,则可以在此处创建一个永无止境的递归周期

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

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