意外的子视图框架(Swift)

时间:2020-06-04 08:21:58

标签: swift

我的代码将我的视图initialview显示为容器containerView的子视图。

我期望initialView.frame是超级视图(即容器视图)坐标中的框架-据报告在游乐场中它是(0,0,0,0)-但这是然后显示在容器中,那么据报道宽度和高度怎么可能为零?

enter image description here

游乐场代码-

final class InitialView: UIView {
    let traverseButton = UIButton(type: .custom)
    let networkButton = UIButton(type: .custom)
    let networkLabel = UILabel()
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

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

    private func setup() {
        self.backgroundColor = .red
        traverseButton.frame = CGRect(x: 0, y: 0, width: 200, height: 100)
        traverseButton.setTitle("Go to Detail", for: .normal)
        traverseButton.setTitleColor(.black, for: .normal)
        traverseButton.isUserInteractionEnabled = true

        self.addSubview(traverseButton)
        traverseButton.translatesAutoresizingMaskIntoConstraints = false
        traverseButton.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        traverseButton.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true

        networkButton.frame = CGRect(x: 0, y: 0, width: 200, height: 100)
        networkButton.setTitle("Make Network Call", for: .normal)
        networkButton.setTitleColor(.black, for: .normal)
        networkButton.isUserInteractionEnabled = true

        self.addSubview(networkButton)
        networkButton.translatesAutoresizingMaskIntoConstraints = false
        networkButton.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        networkButton.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 100).isActive = true

        networkLabel.text = "No network calls made"
        networkLabel.backgroundColor = .purple
        self.addSubview(networkLabel)

        networkLabel.translatesAutoresizingMaskIntoConstraints = false
        networkLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        networkLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 200).isActive = true
        networkLabel.widthAnchor.constraint(equalToConstant: 300).isActive = true
        networkLabel.heightAnchor.constraint(equalToConstant: 100).isActive = true
    }

    func setNetworkLabel(text: String){
        networkLabel.text = text
    }
}

var initialView: InitialView?
initialView = InitialView()

let containerView = UIView(frame: CGRect(x: 10, y: 0, width: 500, height: 1000))
containerView.addSubview(initialView!)

initialView?.translatesAutoresizingMaskIntoConstraints = false

initialView?.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
initialView?.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
initialView?.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
initialView?.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true

1 个答案:

答案 0 :(得分:1)

您可能已将initialView?.frame行放在之前 containerView行中。

尽管您已经添加了约束,但是在Xcode游乐场实际上渲染 containerView之前,尚未布置其子视图。这就是initialView的帧保持其默认值(0, 0, 0, 0)的原因。如果您实际上是手动告诉containerView应该布置其子视图,则initialView的框架将正确设置。

有很多方法可以做到这一点:

  • 将检查initialView?.frame的行移到检查containerView的行之后
  • 先致电containerView.setNeedsLayout()
  • 先致电containerView.layoutIfNeeded()
相关问题