Joon
Joon

Reputation: 11

Why is KeyboardLayoutGuide not applied in viewIsAppearing() in iOS 15.0?

Since viewIsAppearing() appeared, I am using addSubview() in viewDidLoad() and applying Constraint in viewIsAppearing().

I placed the SearchBar at the bottom of the screen, and used UIKeyboardLayoutGuide to move the SearchBar according to the position of the keyboard. It is similar to the search bar in Safari.

There was no problem with iOS 17.0 or higher based on the simulator. Also, there was no problem with version 16.4 of the simulator.

-----

At this time, the problem is as follows:

However, as a result of using the 15.0 and 15.2 versions of the simulator, the SearchBar did not appear on the screen.

When it was fixed to the bottom of the screen based on the safearea without using KeyboardLayoutGuide, it appeared on the screen normally. So I thought there was a problem with UIKeyboardLayoutGuide.

Finally, when I moved the code specifying the layout of the SearchBar that applied UIKeyboardLayoutGuide from viewIsAppearing() to viewDidLoad(), I confirmed that it appeared on the screen normally.

-----

But I don't understand this behavior. The minimum supported version of UIKeyboardLayoutGuide is iOS 15.0. Additionally, the minimum supported version of viewIsAppearing() is iOS 13.0.

Could you tell me what I missed?

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

=================

I would like to add the additional facts I just noticed.

When the layout of the SearchBar performed in viewDidLoad() returns after switching to the Navigation screen, the SearchBar is not visible.

I used viewWillAppear() to solve this problem.

======= This is code for Test (Set simulator version to 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)
    }
}

Upvotes: 0

Views: 461

Answers (2)

matt
matt

Reputation: 535890

You've found a glitch in the relationship between viewIsAppearing and the keyboard layout guide in iOS 15. If you print out the description of the keyboard layout guide into the Xcode console in viewIsAppearing, you will see that in iOS 15 it has effectively no size or position — it's just not ready. And the view debugger tells you that the search view's vertical position is ambiguous.

Personally, I'm not surprised by this. viewIsAppearing was not introduced until iOS 17. It was said at that time to be backwards compatible all the way to iOS 13, but I mean, come on, really? I don't trust that sort of magical backwards compatibility and neither should you. And this is a case in point.

Upvotes: 0

Blazej SLEBODA
Blazej SLEBODA

Reputation: 9925

There is an issue reported on the official forum for Apple developers which says that UIKit below version 16 can have issues with the method viewIsAppearing, such as not working as expected or even not being executed at all.

Maybe you are in such an edge case. If you find a bug, it would be great to share it with on the official forum as well.

Here is citation of response by of Framework developer: There is a known issue with the viewIsAppearing(:) callback when running on older iOS versions (prior to iOS 16) where it may not be called in certain circumstances when you have nested child view controllers. If you are still supporting those older iOS versions and encounter a situation like this, you will need to implement a workaround in your app when running on those older versions to ensure that the code you would normally run in viewIsAppearing(:) still executes when you need it to.

Link to the post: viewIsAppearing not be called in children Controllers below iOS 16?

Upvotes: 0

Related Questions