自从 viewIsAppearing() 出现后,我在 viewDidLoad() 中使用 addSubview() 并在 viewIsAppearing() 中应用 Constraint。
我将SearchBar放置在屏幕底部,并使用UIKeyboardLayoutGuide根据键盘的位置移动SearchBar。它类似于 Safari 中的搜索栏。
基于模拟器,iOS 17.0以上版本没有问题。另外,16.4版本的模拟器也没有问题。
-----
此时问题如下:
但是由于使用了15.0和15.2版本的模拟器,SearchBar并没有出现在屏幕上。
当不使用KeyboardLayoutGuide基于safearea固定到屏幕底部时,它正常出现在屏幕上。所以我认为UIKeyboardLayoutGuide有问题。
最后,当我将指定应用 UIKeyboardLayoutGuide 的 SearchBar 布局的代码从 viewIsAppearing() 移至 viewDidLoad() 时,我确认它正常出现在屏幕上。
-----
但我不理解这种行为。 UIKeyboardLayoutGuide 的最低支持版本是 iOS 15.0。此外,viewIsAppearing() 的最低支持版本是 iOS 13.0。
你能告诉我我错过了什么吗?
override func viewDidLoad() {
super.viewDidLoad()
addSubviews()
layout() // appeared searchBar
}
// ======================================
override func viewDidLoad() {
super.viewDidLoad()
addSubviews()
}
override func viewIsAppearing(_ animated: Bool) {
super.viewIsAppearing(animated)
layout() // not appeared searchBar
}
// ======================================
func layout() { // SearchBar layout Code
let searchBarHeight = 50
collectionView.snp.makeConstraints {
$0.top.equalTo(view.safeAreaLayoutGuide)
$0.horizontalEdges.equalTo(view.safeAreaLayoutGuide)
$0.bottom.equalTo(view.safeAreaLayoutGuide).offset(-searchBarHeight)
}
searchBar.snp.makeConstraints {
$0.height.equalTo(searchBarHeight)
$0.left.equalTo(view.safeAreaLayoutGuide)
$0.bottom.equalTo(view.keyboardLayoutGuide.snp.top)
}
registButton.snp.makeConstraints {
$0.height.equalTo(searchBarHeight)
$0.left.equalTo(searchBar.snp.right)
$0.right.equalTo(view.safeAreaLayoutGuide)
$0.bottom.equalTo(view.keyboardLayoutGuide.snp.top)
$0.width.equalTo(100)
}
}
==================
我想添加我刚刚注意到的其他事实。
切换到导航屏幕后,在 viewDidLoad() 中执行的 SearchBar 布局返回时,SearchBar 不可见。
我使用 viewWillAppear() 来解决这个问题。
======== 这是测试代码(将模拟器版本设置为15.0)
import UIKit
import SnapKit
final class ViewController: UIViewController {
private let uiTextField: UITextField = {
$0.placeholder = "search"
$0.backgroundColor = .red
return $0
}(UITextField())
override func viewIsAppearing(_ animated: Bool) {
super.viewIsAppearing(animated)
view.backgroundColor = .white
layout()
}
private func layout() {
view.addSubview(uiTextField)
uiTextField.snp.makeConstraints {
$0.height.equalTo(50)
$0.horizontalEdges.equalToSuperview()
$0.bottom.equalTo(view.keyboardLayoutGuide.snp.top)
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)
}
}
Apple 开发者官方论坛上报告了一个问题,称版本 16 以下的 UIKit 可能会出现 viewIsAppearing 方法的问题,例如无法按预期工作,甚至根本不执行。
也许你正处于这种边缘情况。如果您发现错误,也最好在官方论坛上分享。
这里引用了框架开发者的回应:有一个 运行时 viewIsAppearing(:) 回调的已知问题 较旧的 iOS 版本(iOS 16 之前)可能无法调用它 当您有嵌套子视图控制器时的某些情况。如果 您仍然支持那些较旧的 iOS 版本并遇到 像这样的情况,您需要在您的系统中实施解决方法 应用程序在旧版本上运行时,以确保您的代码 通常会在 viewIsAppearing(:) 中运行,但在您需要时仍然会执行
您发现 iOS 15 中
viewIsAppearing
和键盘布局指南之间的关系存在问题。如果您在 viewIsAppearing
中将键盘布局指南的描述打印到 Xcode 控制台中,您将在 iOS 15 中看到这一点它实际上没有大小或位置——它只是还没有准备好。并且视图调试器告诉您搜索视图的垂直位置不明确。
就我个人而言,我对此并不感到惊讶。
viewIsAppearing
直到iOS 17才被引入。当时据说可以一直向后兼容到iOS 13,但我的意思是,来吧,真的吗?我不相信那种神奇的向后兼容性,你也不应该相信。这就是一个恰当的例子。