viewWillTransition дает неправильный размер
Я делаю пользовательскую клавиатуру. Я хочу сгенерировать ширину и высоту ключей (UIButtons) на основе ширины и высоты представления.
Когда клавиатура загружена изначально, viewDidAppear правильно определяет высоту представления. (375 х 216)
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.renderKeys()
}
При повороте в альбомную ориентацию он вызывает viewWillTransition
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
NSLog("toSize \(size.width) x \(size.height)")
coordinator.animate(alongsideTransition: {(_ context: UIViewControllerTransitionCoordinatorContext) -> Void in
NSLog("animating \(self.view.frame.width) x \(self.view.frame.height)")
}, completion: {(_ context: UIViewControllerTransitionCoordinatorContext) -> Void in
NSLog("animationCompleted \(self.view.frame.width) x \(self.view.frame.height)")
self.renderKeys()
})
}
Возвращаясь к Портрету, получим это
Я обнаружил, что размер viewWillTransition не правильно определяет размер, которым будет вид, или я просто неправильно понимаю использование функции. Даже после анимации я не могу получить правильную ширину и высоту вида.
Вот отладочный журнал по порядку.
[28651:1348399] Calling viewDidAppear
[28651:1348399] Cleaning keys
[28651:1348399] toSize 667.0 x 216.0
[28651:1348399] animating 667.0 x 216.0
[28651:1348399] animationCompleted 667.0 x 216.0
[28651:1348399] Cleaning keys
[28651:1348399] toSize 375.0 x 162.0
[28651:1348399] animating 375.0 x 162.0
[28651:1348399] animationCompleted 375.0 x 162.0
1 ответ
Я также работаю над пользовательской клавиатурой и обнаружил похожую проблему.
После нескольких часов экспериментов я узнал следующее:
- Когда вы запускаете клавиатуру как приложение, представления загружаются только один раз, и жизненный цикл приложения завершается, как и ожидалось (
application(didFinishLaunchingWithOptions:)
,applicationDidBecomeActive
и т. д.) - Все ориентационные переходы могут быть зафиксированы в
viewWillTransition(to size:)
, например, в iPhone 8+ размер отчета будет равен (414.0, 736.0) или (736.0, 414.0)
Теперь, запустив проект в качестве цели клавиатуры: -
- Система не соответствует обычному жизненному циклу приложения:
application(didFinishLaunchingWithOptions:
),applicationDidBecomeActive
и т.д. не сообщается- Каждый раз, когда устройство меняется с вертикального на горизонтальное или наоборот, основной
ViewController
загружен. - Попытка захватить viewSize в
viewDidLoad
может быть сложно, учитывая, что вам может потребоваться задержка (используяTimer.scheduledTimer(withTimeInterval:)
по крайней мере в первой итерации - ViewSize сообщается в
updateViewConstraints()
, но размер кажется не совсем надежным. После каждого перехода в книжный режим он может сообщать о размере 414 x 736 (размер экрана) или 414 x 226 (правильный размер клавиатуры). В случае iPhone 8+ - Учитывая это конкретное управление жизненным циклом приложения,
viewWillTransition
Метод не выполняется при переходе от Портрета к Пейзажу или от Пейзажа к Портрету (я полагаю, это связано с жизненным циклом вида, который прерывается при каждом повороте). - Он выполняется при переходе от LandscapeLeft к LandscapeRight (через UpsideDown, который не включен) и сообщает правильный размер (736 x 162 в iPhone 8+)
- Каждый раз, когда устройство меняется с вертикального на горизонтальное или наоборот, основной
Итак, что я делаю, чтобы захватить размер экрана в viewDidLoad
после задержки и забыть о updateViewConstraints
или же viewWillTransition(to size:)
Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { (nil) in
print("Load Size: \(self.view.frame.size)")
}
ПРИМЕЧАНИЕ * Эта задержка, по-видимому, необходима только при первой загрузке (в этом случае даже updateViewConstraints
выполняется раньше viewDidLoad
, В следующих итерациях viewDidLoad это не требуется. Также. Вы можете поэкспериментировать с задержкой и протестировать на реальных устройствах против симулятора
Справочная таблица:
Устройство - (Экран) - (KeyboardPortrait) - (KeyboardLandscape)
iPhone X - (375 x 812) - (375 x 141) - (662 x 131)
iPhone 8+ - (414 x 736) - (414 x 226) - (736 x 162)
iPhone 7 + / 8 + - (414 x 736) - (414 x 226) - (736 x 162)
iPhone 7/8 - (375 x 667) - (375 x 216) - (667 x 162)
6 / 6s / 6 + / 6s + - То же, что iPhone 7/8
iPhone SE - (320 x 568) - (320 x 216) - (568 x 162)
Я надеюсь, что это помогает. С уважением... е