簡體   English   中英

iOS如何在輸入視圖更改時獲取鍵盤高度?

[英]iOS How to get keyboard height when the inputview is changed?

我試圖在鍵盤上方放置一個textview。 鍵盤有兩個視圖-一個默認視圖和一個自定義視圖。 有一個按鈕可在這兩個鍵盤之間切換。

我試圖使用以下代碼將textview定位在鍵盤上方。 但是它表現得很奇怪。 keyboardWillShow通知並非一直被調用。

注意:我希望它同時支持縱向和橫向。

class ViewController: UIViewController {

    let textView = UITextView()
    let button = UIButton()

    var keyboardHeight: CGFloat = 0
    var keyboardView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        textView.backgroundColor = .lightGray
        button.backgroundColor = .red
        self.view.addSubview(textView)
        self.view.addSubview(button)
    }

    @objc func buttonAction() {
        if self.textView.inputView == nil {
            self.textView.inputView = keyboardView
            self.textView.inputView?.autoresizingMask = .flexibleHeight
            self.textView.reloadInputViews()
            textView.frame = CGRect(x: 0, y: self.view.frame.size.height - self.textView.inputView!.frame.size.height - 50, width: self.view.frame.size.width - 50, height: 50)
            button.frame = CGRect(x: self.view.frame.size.width - 50, y: self.view.frame.size.height - self.textView.inputView!.frame.size.height - 50, width: 50, height: 50)
        } else {
            self.textView.inputView = nil
            self.textView.reloadInputViews()
            textView.frame = CGRect(x: 0, y: self.view.frame.size.height - self.keyboardHeight - 50, width: self.view.frame.size.width - 50, height: 50)
            button.frame = CGRect(x: self.view.frame.size.width - 50, y: self.view.frame.size.height - self.keyboardHeight - 50, width: 50, height: 50)
        }
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        textView.frame = CGRect(x: 0, y: self.view.frame.size.height - self.keyboardHeight - 50, width: self.view.frame.size.width - 50, height: 50)
        button.frame = CGRect(x: self.view.frame.size.width - 50, y: self.view.frame.size.height - self.keyboardHeight - 50, width: 50, height: 50)
    }

    @objc func keyboardWillShow(notification: Notification) {
        if let userInfo = notification.userInfo {
            if let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
                self.keyboardHeight = keyboardFrame.size.height
                textView.frame = CGRect(x: 0, y: self.view.frame.size.height - self.keyboardHeight - 50, width: self.view.frame.size.width - 50, height: 50)
                button.frame = CGRect(x: self.view.frame.size.width - 50, y: self.view.frame.size.height - self.keyboardHeight - 50, width: 50, height: 50)
            }
        }
    }
}

如果您想在自定義鍵盤和系統鍵盤之間切換時更改鍵盤框架,從而獲得鍵盤的高度,則可以采用多種方法來實現。

我個人不希望通知總是總是給我一個離散的值,盡管在大多數實時情況下,當您需要實時更改鍵盤框架時需要修改UI時,它們已經足夠好了(例如,嘗試在滾動tableView上關閉鍵盤)當您移動鍵盤時,鍵盤會隨着您的手指向下移動,並且當鍵盤向下滾動時,您需要實時對齊視圖)

無論如何,我相信以下說明的方法也應該有助於您在切換時獲得准確的鍵盤高度

第1步:

創建UIView的子類,稍后將其作為輸入附件視圖添加到textView / textField中

protocol KeyBoardObserverProtocol : NSObjectProtocol {
    func keyboardFrameChanged(frame : CGRect)
}

class KeyboardObserverAccessoryView: UIView {
    weak var keyboardDelegate:KeyBoardObserverProtocol? = nil
    private var kvoContext: UInt8 = 1

    override func willMove(toSuperview newSuperview: UIView?) {
        if newSuperview == nil {
            self.superview?.removeObserver(self, forKeyPath: "center")
        }
        else{
            newSuperview?.addObserver(self, forKeyPath: "center", options: [NSKeyValueObservingOptions.new, NSKeyValueObservingOptions.initial], context: &kvoContext)
        }
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if let theChange = change as [NSKeyValueChangeKey : AnyObject]?{
            if theChange[NSKeyValueChangeKey.newKey] != nil{
                if self.keyboardDelegate != nil && self.superview?.frame != nil {
                    self.keyboardDelegate?.keyboardFrameChanged(frame: (self.superview?.frame)!)
                }
            }
        }
    }
}

雖然代碼看起來很大而且很亂,但是里面的內容卻很容易理解。 它所做的只是在收到調用willMove(toSuperview newSuperview: UIView?)開始使用KVO觀察父視圖框架,因為那是當您知道您的視圖已移至父視圖並且您知道現在需要監視父框架時。

每次您的KVO觸發新值時,您都會使用委托將其告知被邀請方

如何使用它?

    keyBoardObserverAccessoryView = KeyboardObserverAccessoryView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
    keyBoardObserverAccessoryView.keyboardDelegate = self
    self.textView.inputAccessoryView = keyBoardObserverAccessoryView

就是這樣:)現在,如果您將來想提供自定義的輸入附件視圖,只需確保您從KeyboardObserverAccessoryView擴展即可,享受到的好處

希望能幫助到你 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM