
I know my code isnt the cleanest, but it bothers me when answers tell the questioner its not a good way or do it this way instead. I am offering a solution NOT using table views or constraints:
In your example, you can use tags for each "level" that needs to be moved. So starting with switch 2 and all views below that, you would have a tag for that level (the second hidden collapsable view would have a tag of 2 as well), then switch 3 would have a tag of 3.
For the labels hidden, you are adding them to a subview i call insideView1 or insideView2. The frames of those inside views should have the proper minX, minY and width, but have a height of 0 to start. Also importantly they have layer.masksToBounds = false, so their subviews dont show when their height is 0. We then animate the height changing to the proper height (expanding), as well as all subviews under changing position.
Lastly i made a dictionary to keep track of when a section is expanded so you can use the same function to expand/collapse other areas while one is already expanded.
import UIKit
class ExpandViewController: UIViewController {
    var insideView1 = UIView()
    var insideView2 = UIView()
    var expand = [1:true,2:true]
    
    @objc func expandCollapse(_ sender : UIButton) {
        var heightChange = CGFloat(0)
        switch sender.tag {
        case 1:
            heightChange = 90
        default:
            heightChange = 90
        }
        var viewsToExpand = [UIView(),insideView1,insideView2]
        
        UIView.animate(withDuration: 1.0) { [self] in
            let expandMe = viewsToExpand[sender.tag]
            if expand[sender.tag] == true {
                expandMe.frame.size.height = heightChange
                for v in view.subviews {
                    if v.tag > sender.tag {
                        v.center.y += heightChange
                    }
                }
            } else {
                expandMe.frame.size.height = 0
                for v in view.subviews {
                    if v.tag > sender.tag {
                        v.center.y -= heightChange
                    }
                }
            }
            expand[sender.tag] = !expand[sender.tag]!
        }
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
     
        let switcher1 = UISwitch()
        switcher1.tag = 1
        switcher1.isOn = false
        switcher1.frame = CGRect(x: view.bounds.width - 150, y: 100, width: 40, height: 30)
        switcher1.addTarget(self, action: #selector(expandCollapse(_:)), for: .allTouchEvents)
        view.addSubview(switcher1)
        let switchLabel1 = UILabel()
        switchLabel1.tag = 1
        switchLabel1.text = "Switch 1"
        switchLabel1.frame = CGRect(x: 30, y: 0, width: view.bounds.width, height: 30)
        switchLabel1.center.y = switcher1.center.y
        view.addSubview(switchLabel1)
        
        let switcher2 = UISwitch()
        switcher2.tag = 2
        switcher2.isOn = false
        switcher2.frame = CGRect(x: view.bounds.width - 150, y: 140, width: 40, height: 30)
        switcher2.addTarget(self, action: #selector(expandCollapse(_:)), for: .allTouchEvents)
        view.addSubview(switcher2)
        let switchLabel2 = UILabel()
        switchLabel2.tag = 2
        switchLabel2.text = "Switch 2"
        switchLabel2.frame = CGRect(x: 30, y: 0, width: view.bounds.width, height: 30)
        switchLabel2.center.y = switcher2.center.y
        view.addSubview(switchLabel2)
        
        let switcher3 = UISwitch()
        switcher3.tag = 3
        switcher3.isOn = false
        switcher3.frame = CGRect(x: view.bounds.width - 150, y: 180, width: 40, height: 30)
//        switcher3.addTarget(self, action: #selector(expandCollapse(_:)), for: .allTouchEvents)
        view.addSubview(switcher3)
        let switchLabel3 = UILabel()
        switchLabel3.tag = 3
        switchLabel3.text = "Switch 3"
        switchLabel3.frame = CGRect(x: 30, y: 0, width: view.bounds.width, height: 30)
        switchLabel3.center.y = switcher3.center.y
        view.addSubview(switchLabel3)
        
        insideView1.frame = CGRect(x: 0, y: switcher1.frame.maxY + 5, width: view.bounds.width, height: 0)
        insideView1.layer.backgroundColor = UIColor.lightGray.cgColor
        insideView1.layer.masksToBounds = true
        insideView1.tag = 1
        view.addSubview(insideView1)
        
        insideView2.frame = CGRect(x: 0, y: switcher2.frame.maxY + 5, width: view.bounds.width, height: 0)
        insideView2.layer.backgroundColor = UIColor.lightGray.cgColor
        insideView2.layer.masksToBounds = true
        insideView2.tag = 2
        view.addSubview(insideView2)
        
        let insideLabel1 = UILabel()
        insideLabel1.text = "Label"
        insideLabel1.frame = CGRect(x: 60, y: 10, width: view.bounds.width, height: 30)
        insideView1.addSubview(insideLabel1)
        let insideTextField1 = UITextField()
        insideTextField1.frame = CGRect(x: 200, y: 0, width: view.bounds.width - 240, height: 30)
        insideTextField1.center.y = insideLabel1.center.y
        insideTextField1.layer.backgroundColor = UIColor.white.cgColor
        insideView1.addSubview(insideTextField1)
        
        let insideLabel2 = UILabel()
        insideLabel2.text = "Label"
        insideLabel2.frame = CGRect(x: 60, y: 50, width: view.bounds.width, height: 30)
        insideView1.addSubview(insideLabel2)
        let insideTextField2 = UITextField()
        insideTextField2.frame = CGRect(x: 200, y: 0, width: view.bounds.width - 240, height: 30)
        insideTextField2.center.y = insideLabel2.center.y
        insideTextField2.layer.backgroundColor = UIColor.white.cgColor
        insideView1.addSubview(insideTextField2)
        
        let insideLabel3 = UILabel()
        insideLabel3.text = "Label"
        insideLabel3.frame = CGRect(x: 60, y: 10, width: view.bounds.width, height: 30)
        insideView2.addSubview(insideLabel3)
        let insideTextField3 = UITextField()
        insideTextField3.frame = CGRect(x: 200, y: 0, width: view.bounds.width - 240, height: 30)
        insideTextField3.center.y = insideLabel3.center.y
        insideTextField3.layer.backgroundColor = UIColor.white.cgColor
        insideView2.addSubview(insideTextField3)
        
        let insideLabel4 = UILabel()
        insideLabel4.text = "Label"
        insideLabel4.frame = CGRect(x: 60, y: 50, width: view.bounds.width, height: 30)
        insideView2.addSubview(insideLabel4)
        let insideTextField4 = UITextField()
        insideTextField4.frame = CGRect(x: 200, y: 0, width: view.bounds.width - 240, height: 30)
        insideTextField4.center.y = insideLabel4.center.y
        insideTextField4.layer.backgroundColor = UIColor.white.cgColor
        insideView2.addSubview(insideTextField4)
    }
}