如何动态设置自定义 UIView class 的高度并将 XIB 添加到垂直堆栈视图?

How can I dynamically set the height of custom UIView class with XIB added to a vertical stackview?

背景资料 我正在创建一个 consent/question 表单应用程序。此表格将有几个不同的问题,文本长度不同。一行最多 5 行,具体取决于设备。

这是我到目前为止所做的 我创建了一个带有 XIB 文件的自定义 UIView class,我在其中添加了一个锚定在顶部的标签(该标签的行设置为 0 = 多行)。此标签将添加短文本或长文本。

在标签下面我有一个 yes/no 按钮作为单选组看起来很像并且在下面我将有一个默认隐藏的 UIText 字段,它只会在某些问题上可见,并且只有当用户selects“是”

问题将添加到位于 UIScrollView 之上的垂直 UIStackview

myQuestionView = MyQuestionView(preDefinedAnswer: false, preDefinedAnswerText: nil)
myQuestionView?.questionLabel.text = "Lorem ipsum dolor sit amet, consectetur adipiscing  ?"
myQuestionView?.shouldShowAnswerTextfield = true
myQuestionView?.heightAnchor.constraint(equalToConstant: 120).isActive = true
 myStackView.addArrangedSubview(myQuestionView!)

问题 正如您在上面的代码中看到的,我将高度限制设置为 120,如果问题只有一行并且用户 DONT select yes(那么视图应该增长并显示 answertextfield ).通常我可能会创建一个高度限制插座并尝试计算 UIView 内的高度 class,但我无法做到这一点。

问题 我如何根据其内容动态设置自定义 UIView class 的高度并使 stackview 相应地增长?我希望在实例化它时高度正确,如果用户单击“是”(以显示 UITextfield)则它会增长。

感谢您的帮助。

UIViewclass

import UIKit

class MyQuestionView: UIView {

    @IBOutlet weak var questionLabel: UILabel!
    @IBOutlet weak var answerTextfield: UITextField!
    @IBOutlet weak var jaButton: UIButton!
    @IBOutlet weak var neiButton: UIButton!
    
    @IBInspectable var height: CGFloat = 300.0
    
    @IBOutlet weak var viewHeight: NSLayoutConstraint!
    
    var shouldShowAnswerTextfield : Bool?
    var answerText : String?
    
    var didAnswerYes : Bool?
    
    /*
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }
    */
    
    init(preDefinedAnswer:Bool?, preDefinedAnswerText:String?)
    {
        super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 200) )
        didAnswerYes = preDefinedAnswer
        answerText = preDefinedAnswerText
        commonInit()
        setup()
        
        
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
        setup()
        print("init")
        
        
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
        setup()
        print("Init?")
        
    }
    
    func commonInit(){
        let viewFromXib = Bundle.main.loadNibNamed("MyQuestionView", owner: self, options: nil)![0] as! UIView
        viewFromXib.frame = self.bounds
        addSubview(viewFromXib)
        

        
    }
    
 
    func setup()
    {
        answerTextfield.isHidden = true
        
        if(didAnswerYes != nil)
        {
            print("Setup \(didAnswerYes)")
            setAnswer(didAnswerYes!)
            
            if(answerText != nil)
            {
                answerTextfield.text = answerText
                if(didAnswerYes!)
                {
                    answerTextfield.isHidden = false

                }
            }
            
        }
        
        
        //sett constraints
        //self.heightAnchor.constraint(equalToConstant: 320).isActive = true
        //self.sizeToFit()
        
        
        
        
        //self.layoutIfNeeded()
        
    }
    

可能的方式:

  1. 使用 table 每个问题的动态单元格视图 view/cell 因此,无需管理更多内容。
  2. 找到label/question/string高度()并计算最终高度,如标签高度+文本字段高度(如果文本字段被隐藏则传零)+其他space和组件高度并将此高度分配给 XIB 高度。
  3. 不给高度限制。正确地为所有 XIB 子视图提供顶部、底部、前导、尾随约束。 有关更多信息,请查看: