首页 > 解决方案 > 子视图的意外帧(Swift)

问题描述

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

我期望initialView.frame成为超级视图(即容器视图)坐标中的框架 - 在操场上报告为(0,0,0,0) - 但它随后显示在容器中,所以怎么能据报道,宽度和高度可能为零?

在此处输入图像描述

操场代码 -

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

标签: swift

解决方案


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

尽管您已经添加了约束,但在 Xcode Playground 实际呈现之前containerView,它的子视图并没有布局。这就是为什么initialView's frame 保持其默认值(0, 0, 0, 0). 如果你真的手动告诉containerView它应该布置它的子视图,那么initialView' 框架将被正确设置。

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

  • 将您检查的行移到您检查initialView?.frame的行之后containerView
  • containerView.setNeedsLayout()先打电话
  • containerView.layoutIfNeeded()先打电话

推荐阅读