为什么 iOS 15.0 中的 viewIsAppearing() 中没有应用 KeyboardLayoutGuide?

问题描述 投票:0回答:2

自从 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)
    }
}

ios uikit autolayout uisearchbar viewcontroller-lifecyle
2个回答
0
投票

Apple 开发者官方论坛上报告了一个问题,称版本 16 以下的 UIKit 可能会出现 viewIsAppearing 方法的问题,例如无法按预期工作,甚至根本不执行。

也许你正处于这种边缘情况。如果您发现错误,也最好在官方论坛上分享。

这里引用了框架开发者的回应:有一个 运行时 viewIsAppearing(:) 回调的已知问题 较旧的 iOS 版本(iOS 16 之前)可能无法调用它 当您有嵌套子视图控制器时的某些情况。如果 您仍然支持那些较旧的 iOS 版本并遇到 像这样的情况,您需要在您的系统中实施解决方法 应用程序在旧版本上运行时,以确保您的代码 通常会在 viewIsAppearing(:) 中运行,但在您需要时仍然会执行

帖子链接:viewIsAppearing 在 iOS 16 以下的子控制器中不会被调用?


0
投票

您发现 iOS 15 中

viewIsAppearing
和键盘布局指南之间的关系存在问题。如果您在
viewIsAppearing
中将键盘布局指南的描述打印到 Xcode 控制台中,您将在 iOS 15 中看到这一点它实际上没有大小或位置——它只是还没有准备好。并且视图调试器告诉您搜索视图的垂直位置不明确。

就我个人而言,我对此并不感到惊讶。

viewIsAppearing
直到iOS 17才被引入。当时据说可以一直向后兼容到iOS 13,但我的意思是,来吧,真的吗?我不相信那种神奇的向后兼容性,你也不应该相信。这就是一个恰当的例子。

© www.soinside.com 2019 - 2024. All rights reserved.