Search code examples
swiftlayoutuiview

UIView layoutSubviews notification


i have a question about UIView layoutSubviews

class ViewController: UIViewController {
    let v1 = SubView1()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        view.addSubview(v1)
        
        v1.frame = CGRect(x: 50, y: 50, width: 70, height: 30)
    }
}

class SubView1: UIView {
    let subView = SubView2()
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        print("layoutSubviews SubView1")
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        var frame = subView.frame
        frame.origin = CGPoint(x: 0, y: 0)
        frame.size.width = 50
        subView.frame = frame
        
        addSubview(subView)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class SubView2: UIView {
    let label = UILabel()
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        print("layoutSubviews SubView2")
        
        var frame = label.frame
        frame.origin = CGPoint(x: 10, y: 10)
        frame.size.width = self.frame.width - 20
        label.frame = frame
        
        label.sizeToFit()
        
        frame = self.frame
        frame.size.height = label.frame.size.height + 20
        self.frame = frame
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        label.numberOfLines = 0
        label.text = "test test test test test test test test"
        
        addSubview(label)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

this code print:

layoutSubviews SubView1
layoutSubviews SubView2

I want to adjust SubView1 so that SubView1 wraps around SubView2.
but SubView2'frmae is determined when 'layoutSubviews SubView2' call. (I don't know in 'layoutSubviews SubView1')

I want to know how to notice SubView1 after 'layoutSubviews SubView2'


Solution

  • The way you are approaching is tough. My suggestion for achieving what you want will be following

    1. Using AutoLayout Layout your desired layout using autolayout constraints. This is the practical way of making production app.

    https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/index.html

    1. Without Autolayout If you insist not to use auto layout, then go for the ‘viewDidLayoutSubviews’ callback. This is a view controller call back, called when all the views are laid out by the view controller. Here you know for sure that, all the subviews in this view controller is laud out.

    https://developer.apple.com/documentation/uikit/uiviewcontroller/1621398-viewdidlayoutsubviews

    among these i prefer auto layout, becuase there is som many things to sort out instead of laying out views in an ios app.