Ios 如何在垂直stackview中添加XIB时动态设置自定义UIView类的高度?

Ios 如何在垂直stackview中添加XIB时动态设置自定义UIView类的高度?,ios,swift,uiview,uistackview,Ios,Swift,Uiview,Uistackview,背景信息 我正在创建一个同意/问题表应用程序。此表单将有几个不同的问题,文本长度不同。一行最多5行,具体取决于设备 这就是我到目前为止所做的 我用一个XIB文件创建了一个自定义UIView类,我在其中添加了一个锚定到顶部的标签(该标签的线设置为0=多行)。此标签将添加短文本或长文本 在标签下面,我有一个与单选组相似的是/否按钮,在标签下面,我将有一个默认隐藏的UIText字段,只有在用户选择“是”时,该字段才会在某些问题上可见 该问题将添加到位于UIScrollView顶部的垂直UIStackv

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

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

在标签下面,我有一个与单选组相似的是/否按钮,在标签下面,我将有一个默认隐藏的UIText字段,只有在用户选择“是”时,该字段才会在某些问题上可见

该问题将添加到位于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,如果问题只有一行,并且如果用户没有选择“是”(则视图应该增长并显示answertextfield),那么这看起来是正常的。通常,我可能会创建一个高度约束出口,并尝试在UIView类中计算高度,但我无法做到这一点

问题 如何根据自定义UIView类的内容动态设置其高度,并使stackview相应增长?我希望在实例化时高度正确,如果用户单击yes(显示UITextfield),高度将增长

谢谢你的帮助

UIView类

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()
        
    }
    
可能的方式:

  • 对每个问题视图/单元格使用带有动态单元格的表视图,这样就无需管理更多内容
  • 找到标签/问题/字符串高度()并计算最终高度,如标签高度+文本字段高度(如果文本字段隐藏,则传递零)+其他空间和组件高度,并将此高度指定给XIB高度
  • 不要给高度限制。正确地为所有XIB子视图提供顶部、底部、前导和尾随约束。 要了解更多信息,请检查以下内容:

  • 谢谢你的帮助:)关于备选方案2:在我的情况下,你会在哪里设置xib的高度备选方案3:我已经这样做了,但没有帮助。xib上的所有子视图都具有自动布局工作所需的所有适当约束。即使我将子视图设置为statick heigt,当它添加到stackview时,它也会被填满。对于第二个备选集,在代码的第一个init中计算高度,您已经设置了200。对于第三种选择,需要堆栈视图的代码,并且需要检查堆栈视图属性。谢谢。init成功了。我是在零度