在添加到子视图之前,如何获得UIView的宽度和高度?

时间:2017-10-21 18:48:10

标签: ios swift uiview

我正在构建一个UIPageViewController,它根据视图数组中的视图高度具有可变数量的页面。

我有一个名为BlockView的课程,如下所示:

final class BlockView: UIView {

    init(viewModel: BlockViewModel) {
        super.init(frame: .zero)

        let primaryLabel = UILabel()
        primaryLabel.text = viewModel.labelText
        addSubview(primaryLabel)

        constrain(primaryLabel) {
            $0.top == $0.superview!.top + 8
            $0.bottom == $0.superview!.bottom - 8
            $0.left == $0.superview!.left + 8
            $0.right == $0.superview!.right - 8
        }  
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

我希望能够做的是遍历我的BlockViews数组并运行print(blockView.frame)并查看不为零的帧。

现在我知道我将frame设置为.zero内的BlockView.init。那是因为我希望视图根据其标签来调整大小。

我需要运行一个功能来实现这个目标吗?

由于

1 个答案:

答案 0 :(得分:1)

尝试sizeThatFits(_:)计算它而不将其放到超级视图中。该方法的唯一参数是CGSize,它表示应显示的边界。例如,如果您知道超级视图的宽度(例如,340点),并且您想知道高度需要多少:

let expectedSize = view.sizeThatFits(CGSize(width: 340, height: .greatestFiniteMagnitude))

但是,您的BlockView似乎尚未设置适当的约束。您使用super.init(frame: .zero)初始化它 - 因此它的大小为0,0。

你的约束并没有改变,例如:

constrain(primaryLabel) {
   $0.centerY == $0.superview!.centerY
   $0.left == $0.superview!.left + 8
}

这看起来像是将标签的Y轴中心设置为块视图的中心,将标签的左锚点设置为视图的左锚点。如果blockView已经具有大小,则可以正确定位标签。但是现在块视图的大小根本不受标签大小的影响。我想你想要将标签限制在blockView的左,右,顶部和底部锚点,这样当你尝试计算blockView的大小时,自动布局必须首先计算标签的大小,并根据此blockView本身的大小。

一种可能的解决方案(我使用基于锚点的自动布局语法),您可以尝试将其放到BlockView的初始值设定项中:

primaryLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 8).isActive = true
primaryLabel.topAchor.constraint(equalTo: self.topAnchor, constant: 8).isActive = true
primaryLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -8).isActive = true
primaryLabel.bottomAnchor.constraint(equalTo: secondaryLabel.topAnchor, constant: -8).isActive = true
secondaryLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 8).isActive = true
secondaryLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -8).isActive = true
secondaryLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -8).isActive = true