Я прочитал всю документацию 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 появится метка на экране.