Ryan
Ryan

Reputation: 4884

Child view controller's viewDidLayout invokes before parent's viewDidLayout

I'm trying to make a view controller which works like .popover modal presentation style view controller. Because a tooltip in child view controller should layout based on parent's sourceView or sourceItem, the child view controller has reference to parent's specific UIView or UIBarButtonItem.

(Because I draw most content in the tool tip, I can't use auto layout.)

I configure child view controller's layout in viewDidLayoutSubviews() and it worked fine, but issue occurs when device orientation changes.

When device orientation is changed, child.viewDidLayoutSubviews() is called before parent.viewDidLayoutSubviews(), and it makes child view controller's configure its layout based on the parent view controller's old layout which is before orientation changes.

It seems the only way to figure out is to call child.view.setNeedsLayout from parent.viewDidLayoutSubviews(), but I want to leave it as a plan B.

Is there a natural way to handle this?

ADDED

I just made a sample project to make sure.

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .yellow
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let vc = ModalViewController()
        vc.modalPresentationStyle = .overCurrentContext
        present(vc, animated: true, completion: nil)
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        print(#file)
    }
}
class ModalViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .purple
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        print(#file)
    }
}

The log was as below:

// when loaded
TestProject/ViewController.swift
TestProject/ModalViewController.swift

// when rotated
TestProject/ModalViewController.swift
TestProject/ViewController.swift

Upvotes: 0

Views: 578

Answers (1)

matt
matt

Reputation: 535306

There is something wrong here. layoutSubviews is propagated from the top down. If that’s not what you’re seeing, perhaps your overrides are somehow subverting the normal mechanisms. Make sure you are calling super in all relevant overrides and that you are not forcing premature layout.

Upvotes: 1

Related Questions