子级视图控制器的viewDidLayout在父级的viewDidLayout之前调用

时间:2019-04-16 21:04:48

标签: ios swift uiviewcontroller orientation

我正在尝试制作一个类似于.popover模态表示样式视图控制器的视图控制器。由于子视图控制器中的工具提示应基于父级的sourceViewsourceItem进行布局,因此子视图控制器可以引用父级的特定UIViewUIBarButtonItem

(因为我在工具提示中绘制了大部分内容,所以不能使用自动布局。)

我在viewDidLayoutSubviews()中配置了子视图控制器的布局,并且工作正常,但是当设备方向更改时会出现问题。

更改设备方向后,child.viewDidLayoutSubviews()parent.viewDidLayoutSubviews()之前被调用,它使子视图控制器根据方向改变之前父视图控制器的旧布局来配置其布局。

似乎唯一的解决方法是从child.view.setNeedsLayout调用parent.viewDidLayoutSubviews(),但我想将其保留为计划B。

有一种自然的方法来处理吗?

添加

我只是做了一个示例项目来确定。

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

日志如下:

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

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

1 个答案:

答案 0 :(得分:1)

这里有问题。 layoutSubviews从上向下传播。如果这不是您所看到的,那么您的替代可能会以某种方式破坏正常的机制。确保在所有相关替代中都调用super,并且不要强行过早布局。