Выполнение следующих строк в вашем приложении каким-то образом сломает клавиатуру и ее панель инструментов. Панель инструментов «отсоединяется» от клавиатуры и начинает скользить вверх и вниз в самой верхней части экрана под строкой состояния.
if #available(iOS 13.0, *) {
for scene in UIApplication.shared.connectedScenes {
guard let windowScene = scene as? UIWindowScene else { continue }
for window in windowScene.windows {
for view in window.subviews {
view.removeFromSuperview()
window.addSubview(view)
}
}
}
} else {
for window in UIApplication.shared.windows {
for view in window.subviews {
view.removeFromSuperview()
window.addSubview(view)
}
}
}
Я знаю, что это очень «взломанно», я просто наткнулся на это, и теперь мне любопытно, почему удаление и добавление представлений вызывает такое поведение. У кого-нибудь есть идея? (Это также происходит с панелями инструментов, которые были добавлены системой, например, в веб-просмотре)
Здесь плохо видно, но вы можете увидеть левую кнопку панели инструментов:
Метод removeFromSuperView()
удалит все ограничения автоматического макета, которые относятся к удаляемому представлению, а также к подвидам этого представления. Они не волшебным образом вернутся к существованию только потому, что вы повторно добавите вид, так что в итоге вы получите то, чем является кадр представления.
Однако, поскольку вы экспериментируете здесь, вы можете попробовать это, чтобы увидеть, восстанавливают ли представления свои ограничения:
for view in window.subviews {
let constr = view.constraints
view.removeFromSuperview()
window.addSubview(view)
NSLayoutConstraint.activate(constr)
}
Проблема в том, что всегда есть несколько окон, одно из которых — UITextEffectsWindow
, отвечающее за отображение клавиатуры (и, возможно, других представлений, так как это частный API, официальной документации для него нет).
Игнорирование UITextEffectsWindow
при перемещении по окнам решит проблему с клавиатурой.
for window in windowScene.windows.reversed() {
if NSStringFromClass(window.classForCoder) == "UITextEffectsWindow" {
NSLog("===== Ignore UITextEffectsWindow")
return
}
for view in window.subviews.reversed() {
view.removeFromSuperview()
window.addSubview(view)
}
}
Но так как UITextEffectsWindow
— это частный API, возможно, вам следует сделать обратное и удалить представления только в том случае, если окно — это UIWindow
.
Это ответ, который я искал, большое спасибо :full_moon_with_face: :P