Я прочитал всю документацию Apple о пользовательских модальных презентациях и не смог найти этот ответ. При представлении контроллера представления с использованием пользовательской анимации мы можем вернуть 3 вещи (если переход не является интерактивным; интерактивный может вернуть 4): контроллер представления и два контроллера анимации (один для настоящего и один для отклонения).
И в контроллере представления, и в настоящем контроллере анимации ни один из кодов Apple не содержит ограничений. Степень обсуждения фреймов - рекомендация Apple установить фрейм представленного представления контроллера представления в существующем контроллере анимации (ниже):
// Always add the "to" view to the container.
// And it doesn't hurt to set its start frame.
[containerView addSubview:toView];
toView.frame = toViewStartFrame;
... и что это.
У меня проблема в том, что строка состояния двойной высоты не распознается этими представленными контроллерами представления в симуляторе (и устройствами, которыми я владею). Точнее, ни одно решение не работает во всех симуляторах - решения, которые работают в новых симуляторах (например, iPhone 8), не работают в старых симуляторах (например, iPhone 5). Если я позволю Apple обработать презентацию с использованием анимации UIKit по умолчанию, строка состояния двойной высоты будет хорошо обрабатываться представленным контроллером представления; поэтому я могу предположить, что ограничения в представленном контроллере представления не являются проблемой.
Поэтому я без особой удачи обратился к методам контроллера презентации containerViewDidLayoutSubviews
и containerViewWillLayoutSubviews
:
override func containerViewDidLayoutSubviews() {
super.containerViewDidLayoutSubviews()
presentedViewController.view.frame = containerView!.bounds
}
Приведенный выше код работает в симуляторе только при первом появлении строки состояния двойной высоты; с этого момента этот метод перестает отвечать на запросы. Чтобы проверить это:
override func containerViewDidLayoutSubviews() {
super.containerViewDidLayoutSubviews()
presentedViewController.view.frame = containerView!.bounds
print("did layout")
}
Приведенный выше метод останавливает печать на консоли после первого введения строки состояния двойной высоты. Но если я изменю задачу на что-то, что не изменит размер представленного фрейма, как, скажем, изменение его фона:
override func containerViewDidLayoutSubviews() {
super.containerViewDidLayoutSubviews()
presentedViewController.view.backgroundColor = UIColor.blue
print("did layout")
}
метод никогда не ломается. По какой-либо причине изменение размера представленного фрейма представления в этом методе нарушает метод после первого переключения строки состояния двойной высоты. Я хотел бы объяснить это поведение. Вряд ли ошибка, но кажется, как один.
Несмотря на это, Apple заявляет, что, если авторазметка используется правильно, программисту ничего не нужно делать! Итак, мой вопрос: где или как мы должны предоставить представленные ограничения представления контроллера представления, чтобы он мог адаптироваться к его временному контейнеру? Потому что, IMO, это проблема. Представленный контроллер представления принадлежит представлению переходного контейнера, которое является временным представлением, предоставленным UIKit, над которым мы не имеем большого доминирования. Если мы сможем привязать представленное представление к этому контейнеру, все проблемы будут решены. Но я никогда не видел, чтобы Apple делала это или даже говорила об этом.
Примечание. Явная привязка представленного представления к представлению контейнера в любом месте - в существующем контроллере аниматора (до анимации или в обработчике его завершения), в контроллере представления или в методе адаптивного делегата - не дает согласованных результатов, как упоминалось ранее.
ВЫВОДЫ: (1) Нет способа официально, правильно, чисто или последовательно обрабатывать строку состояния двойной высоты с модальными презентациями; (2) Apple испортила его с помощью строки состояния двойной высоты и не может дождаться того дня, когда на всех iPhone появится метка на экране.