1

我正在尝试将包含多个标签的 xib 中的 UIStackView 加载到父 UIStackView 中。viewDidLoad子堆栈中的标签通过模型对象在方法中的 ViewController 之后填充值(或隐藏) 。

我希望父 stackview 能够识别子 stackview 内在高度的变化,从而将兄弟视图向下移动。但是,下一个视图(按钮)覆盖了子堆栈的内容。为什么父级不能识别子视图高度的这种变化?我没有看到任何错误消息、模棱两可的约束或冲突。

以下是错误的呈现方式以及视图在 View Hierarchy 中的显示方式。 在此处输入图像描述

我努力了:

  • 在子堆栈视图周围添加 UIView 包装器,以查看父级是否会注册其高度的更改。
  • 将所有代码移到父视图控制器中,避免加载 xib,这似乎确实有效,但代价是失去了模块化和关注点分离。
  • 根据其他文章推荐对子 stackview 添加了可选的高度约束,导致位置不随内容弯曲,或无法解决原始问题。

这是故事板布局 显示父堆栈(主堆栈)和子堆栈(信息视图)的情节提要

父视图控制器

class AcceptTermsViewController: RegistrationViewController {
    
    @IBOutlet weak var infoView: StackViewInBorderedView!
    @IBOutlet weak var termsView: TermsTextView!
    @IBOutlet weak var masterStack: UIStackView!
    
    var registration: Registration?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.configView()
        self.setupNavBar()
    }

    func configView() {
        if let reg = registration {
            infoView.configView(reg)
        }
    }
}

子 StackView 代码

class StackViewInBorderedView: UIStackView {
    // loaded from NIB
    private weak var view: UIView!
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var emailLabel: UILabel!
    @IBOutlet weak var locationLabel: UILabel!
    @IBOutlet weak var postalLabel: UILabel!
    @IBOutlet weak var idLabel: UILabel!
    @IBOutlet weak var npiLabel: UILabel!
    
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        loadViewFromNib()
    }
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        loadViewFromNib()
    }
    
    fileprivate func loadViewFromNib() {
        self.view = Bundle (for: type(of: self)).loadNibNamed(
            "StackViewInBorderedView", owner: self, options: nil)! [0] as? UIView
        view.frame = bounds
        view.autoresizingMask = [.flexibleWidth]
        self.addSubview(view)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        self.layer.cornerRadius = 10
        let shadowLayer = CAShapeLayer()
        shadowLayer.path = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.frame.height / 12).cgPath
        shadowLayer.fillColor = UIColor.white.cgColor
        shadowLayer.shadowColor = UIColor.gray.cgColor
        shadowLayer.shadowOffset = CGSize.zero
        shadowLayer.shadowOpacity = 1
        shadowLayer.shadowRadius = 3
        shadowLayer.masksToBounds = false
        self.layer.insertSublayer(shadowLayer, at: 0)
    }
    
    func configView(_ reg: Registration) {
        configLabels(reg)
        
        isLayoutMarginsRelativeArrangement = true
        directionalLayoutMargins = NSDirectionalEdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 0)
        
    }
    
    func configLabels(_ reg: Registration) {
        
        // Name line
        if let degree = reg.degree {
            nameLabel.text = "\(reg.firstName!) \(reg.lastName!), \(degree)"
        } else {
            nameLabel.text = "\(reg.firstName!) \(reg.lastName!)"
        }
        
        // Title line
        if let title = reg.title {
            titleLabel.text = title
        } else {
            titleLabel.isHidden = true
        }
        
        // Email line
        if let email = reg.email {
            emailLabel.text = email
        } else {
            emailLabel.isHidden = true
        }
        
        // Location line
        if let city = reg.city, let state = reg.state, let postal = reg.postalCode,
            !city.isEmpty, !state.isEmpty, !postal.isEmpty {
            postalLabel.text = "\(city), \(state) \(postal)"
        } else if let postal = reg.postalCode {
            postalLabel.text = postal
        }
        
        // NPI line
        if let licenseId = reg.licenseId {
            switch reg.countryCode {
            case "BR":
                idLabel.text = "ID"
            default:
                idLabel.text = "NPI"
            }
            npiLabel.text = licenseId
        } else {
            self.idLabel.isHidden = true
            self.npiLabel.isHidden = true
        }
    }
}

4

1 回答 1

1

我的一位同事找到了答案。

从笔尖加载视图时,我需要调用self.addArrangedSubview而不是调用self.addSubview它来提供预期的行为。

于 2020-08-11T18:06:43.553 回答