【问题标题】:Is there a way to tell iOS to update the keyboard appearance within a view controller?有没有办法告诉 iOS 更新视图控制器中的键盘外观?
【发布时间】:2019-05-03 10:51:54
【问题描述】:

我想在ViewController 中更新UIKeyboardAppearance。我的意思是说,VC 加载了UIKeyboardAppearance.default。如果我按下一个按钮,我希望键盘更新为.dark,并让键盘现在显示在与.dark 相同的VC 中。

据我所知,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 中强制重新检查?

感谢您的帮助!

【问题讨论】:

    标签: ios swift uiviewcontroller uikeyboard


    【解决方案1】:

    您可以递归地更改屏幕上所有文本字段的键盘外观(allSubviewsOf(type:) 扩展名来自 this great answer by 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
    

    【讨论】:

      【解决方案2】:

      感谢 Tamás 的回答!

      它引导我找到我需要的东西。

      如果您更改 UITextField 的键盘外观,看起来就像

      UITextField.appearance().keyboardAppearance = .dark
      

      系统仅检查 VC 负载。如果您为每个文本字段更改它

      myTextBox.keyboardAppearance = .dark
      

      系统将检查每次 firstResponder 更改并加载正确的键盘。

      再次感谢 Tamás!

      【讨论】:

        猜你喜欢
        • 2015-09-01
        • 2011-06-27
        • 2013-06-18
        • 2015-11-06
        • 2020-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-23
        相关资源
        最近更新 更多