Хорошо, я нашел простое решение. Я делал ошибку новичка. Хитрость заключается в том, чтобы переопределить viewWillLayoutSubviews()
вместо viewWillAppear(animated:)
. Тогда все работает как я хочу. Кажется, что viewWillLayoutSubviews()
вызывается (иногда более одного раза) каждый раз, когда содержащий UISplitViewController
меняет свой режим отображения, и это именно то, на что я должен ответить. Единственная ошибка в том, что splitViewController
может быть nil
для некоторых из этих вызовов, поэтому его необходимо реализовать следующим образом:
override func viewWillAppear(_ animated: Bool) {
if let svc = splitViewController {
if svc.primaryHidden {
// hide the "close" UI artifact
} else {
// show the "close" UI artifact
}
}
}
В процессе поиска решения я попытался переопределить traitCollectionDidChange(previousTraitCollection:)
. (Я попробовал это, потому что хотел отреагировать на повороты устройства.) Сначала я подумал, что на что-то натолкнулся, потому что эта функция также вызывается всякий раз, когда устройство вращается. Интересно (и, к сожалению), я обнаружил, что свойство splitViewController
моего представления было nil
, когда эта функция вызывается. Кажется странным, что это должно быть так, поскольку ни viewDidDisappear(animated:)
, ни viewWillAppear(animated:)
не вызывается, когда UISplitViewController переконфигурирует себя. Но почему это должно быть nil
, я полагаю, вопрос на другой день.