0

Background info I am creating a consent/question form application. This form will have several different questions with text in different lengths. One line up to 5 lines depending on the device.

This is what i have done so far I have created a custom UIView class with an XIB file where i have added one Label anchored to the top (Lines set to 0 = multiline for that label). This label will a short or a long text added to it.

Underneath the label i have a yes/no buttons as radio group lookalike and under there again I will have a UIText field hidden by default, that will only be visible on some of the question and only if the user selects "Yes"

The question will be added to a vertical UIStackview who sits on top of a UIScrollView

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!)

The XIB file

The problem As you can see in the code above, I am setting the height constraint to 120, and that looks ok if the question is only one line and if the user DONT select yes (then the view should grow and show the answertextfield). Normally i would maybe created a height constraint outlet and tried to calculate the height within the UIView class, but I am not able to to that.

The question How can i dynamically set the height of my custom UIView class based on its content AND get the stackview to grow accordingly? I want the height to be correct when i instantiate it and the grow if the user clicks yes (to show the UITextfield).

Thanks for any help.

The UIView class

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()
        
    }
    
BluE_MoOn
  • 103
  • 10

1 Answers1

1

Possible ways:

  1. Use table view with the dynamic cell for each question view/cell so, no need to manage more things.
  2. Find the label/question/string height (https://stackoverflow.com/a/30450559/14733292) and calculate the final height like label height + text field height (if the text field is hidden then pass zero) + other space and component height and assign this height to XIB height.
  3. Don't give height constraint. Give top, bottom, leading, trailing constraint to all XIB subview properly. For more check this: https://stackoverflow.com/a/47216020/14733292
Raja Kishan
  • 16,767
  • 2
  • 26
  • 52
  • Thanks for trying to help :) Regarding alternativ 2 : Where would you set the height of the xib in my case Alternativ 3: I have done that, but it doesnt help. All subviews on the xib has all proper constraints for autolayout to work. Even if i set subviews to statick heigt its all crammed when its added to the stackview. – BluE_MoOn Dec 10 '20 at 14:22
  • For the second alternative set calculate height in your first init in your code you have set 200. For the third alternative need code for stack view and need to check the stack view property. – Raja Kishan Dec 10 '20 at 16:07
  • Thank you. The init did the trick. I had it at .zero – BluE_MoOn Dec 10 '20 at 21:31