有没有一种方法可以告诉iOS在视图控制器中更新键盘外观?

4
我想更新ViewController中的UIKeyboardAppearance。我的意思是,假设VC加载时使用的是UIKeyboardAppearance.default,如果我按下按钮,我想将键盘更新为.dark,并且在同一VC中以.dark显示键盘。

据我所知,iOS在加载VC时会检查UIKeyboardAppearance的值,并且直到再次加载VC之前不会再次检查。即使您更改了UIKeyboardAppearance的值并隐藏/显示了键盘。
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

// creating a simple text box, and making the placeholder text the value of the keyboardAppearance
        myTextBox.backgroundColor = UIColor.lightGray
        myTextBox.frame = CGRect(x: 30, y: 200, width: 300, height: 50)
        view.addSubview(myTextBox)
        UITextField.appearance().keyboardAppearance = .dark
        myTextBox.becomeFirstResponder()
        myTextBox.placeholder = "Keybaoard Appearance is: \(UITextField.appearance().keyboardAppearance.rawValue)"

// a simple button to toggle the keyboardAppearance
        toggleButton.frame = CGRect(x: 30, y: 300, width: 300, height: 50)
        toggleButton.setTitle("Toggle Keyboard", for: .normal)
        toggleButton.backgroundColor = UIColor.red
        toggleButton.addTarget(self, action: #selector(toggleButtonFunction), for: .touchUpInside)
        view.addSubview(toggleButton)

    }

// toggles the keyboardAppearance. Hides the keyboard, and a second later shows it again.
    @objc func toggleButtonFunction() {
        if UITextField.appearance().keyboardAppearance == .dark {
            UITextField.appearance().keyboardAppearance = .default
        }
        else {
            UITextField.appearance().keyboardAppearance = .dark
        }
        myTextBox.resignFirstResponder()
        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1), execute: {
            self.myTextBox.becomeFirstResponder()
            self.myTextBox.placeholder = "Keybaoard Appearance is: \(UITextField.appearance().keyboardAppearance.rawValue)"

            })
    }

    let myTextBox = UITextField()
    let toggleButton = UIButton()
}

我希望更改UIKeyboardAppearance并隐藏/显示键盘后,它能以新的外观(.dark.default)显示,但直到重新加载VC之前,它仍然以相同的外观显示。您可以看到UIKeyboardAppearance的值已更改,但是iOS似乎直到VC再次加载才会检查该更新。
是否有一种方法在VC中强制重新检查?
感谢您的帮助!
2个回答

1
你可以递归更改屏幕上所有文本字段的键盘外观(allSubviewsOf(type:) 扩展来自 Mohammad Sadiq 的这个很棒的答案):
func changeTextFieldKeyboardAppearance() {
    UITextField.appearance().keyboardAppearance = .dark

    let textFields = view.allSubviewsOf(type: UITextField.self)

    let firstResponder = textFields.first { $0.isFirstResponder }

    firstResponder?.resignFirstResponder()

    textFields.forEach { $0.keyboardAppearance = .dark }

    firstResponder?.becomeFirstResponder()
}

[...]

extension UIView {
    func allSubviewsOf<T: UIView>(type: T.Type) -> [T] {
        var all = [T]()

        func getSubview(view: UIView) {
            if let aView = view as? T {
                all.append(aView)
            }

            guard !view.subviews.isEmpty else {
                return
            }

            view.subviews.forEach{ getSubview(view: $0) }
        }

        getSubview(view: self)

        return all
    }
}

如果您的视图控制器嵌入在一个 UITabBarController 中,您可以通过更改其 selectedIndex 并立即将其改回原始索引来触发更新:
guard let tabBarController = tabBarController else {
    return
}

let selectedIndex = tabBarController.selectedIndex

UITextField.appearance().keyboardAppearance = .dark

tabBarController.selectedIndex = selectedIndex == 1 ? 0 : 1
tabBarController.selectedIndex = selectedIndex

0

感谢Tamás的回答!

它引导我走上了发现我所需的东西的道路。

看起来,如果您更改UITextField的keyboardAppearance,则会发生变化。

UITextField.appearance().keyboardAppearance = .dark

系统只检查VC负载。如果你为每个textField更改它

myTextBox.keyboardAppearance = .dark

系统将在每次firstResponder更改时检查并加载正确的键盘。
再次感谢Tamás!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接