问题描述
我试图将包含多个标签的xib中的UIStackView加载到父UIStackView中。在子堆栈中的标签通过模型对象在viewDidLoad
方法中的ViewController之后填充(或隐藏)值。
我希望父stackview能够识别子stackview的固有高度的变化,从而将同级视图下移。但是,下一个视图(按钮)涵盖了子堆栈的内容。为什么父级无法识别子视图高度的这种变化?我没有看到任何错误消息,模棱两可的约束或冲突。
我尝试过:
- 在子堆栈视图周围添加一个UIView包装器,以查看父级是否会记录其高度的变化。
- 将所有代码移动到父视图控制器中,避免了xib加载,并且看起来确实可行,但代价是失去了模块化和关注点分离。
- 根据其他文章建议,在子堆栈视图上添加了可选的高度限制,导致位置不随内容而变,或者无法解决原始问题。
父视图控制器
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
}
}
}
解决方法
我的一个同事找到了答案。
从笔尖加载视图时,我需要调用self.addArrangedSubview
而不是self.addSubview
来提供预期的行为。