iOS keyboard 高度監(jiān)聽(tīng)

原文鏈接:
https://www.hackingwithswift.com/read/19/7/fixing-the-keyboard-notificationcenter

實(shí)現(xiàn)代碼:

class ViewController: UIViewController {

    lazy var script: UITextView = {
        let d = UITextView(frame: UIScreen.main.bounds)
        return d
    }()
        
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        view.addSubview(script)
        
        addNotifi()
        
    }

    @objc func addNotifi() {
        let notificationCenter = NotificationCenter.default
        notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)
        notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
    }

    @objc func adjustForKeyboard(notification: Notification) {
        guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }

        let keyboardScreenEndFrame = keyboardValue.cgRectValue
        let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)

        if notification.name == UIResponder.keyboardWillHideNotification {[圖片上傳中...(QQ20200516-162120.gif-b5310a-1589617305797-0)]

            script.contentInset = .zero
        } else {
            script.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height - view.safeAreaInsets.bottom, right: 0)
        }

        script.scrollIndicatorInsets = script.contentInset

        let selectedRange = script.selectedRange
        script.scrollRangeToVisible(selectedRange)
    }
}

實(shí)現(xiàn)原理:
我們可以要求使用新的類來(lái)告知鍵盤(pán)狀態(tài)何時(shí)更改NotificationCenter。在幕后,iOS會(huì)在發(fā)生事情時(shí)不斷發(fā)出通知-鍵盤(pán)更換,應(yīng)用程序移至后臺(tái)以及應(yīng)用程序發(fā)布的任何自定義事件。我們可以將自己添加為某些通知的觀察者,并且在通知發(fā)生時(shí)將調(diào)用我們命名的方法,甚至將傳遞任何有用的信息。

使用鍵盤(pán)時(shí),我們關(guān)注的通知是keyboardWillHideNotificationkeyboardWillChangeFrameNotification。當(dāng)鍵盤(pán)完成隱藏時(shí),將發(fā)送第一個(gè),而在發(fā)生任何鍵盤(pán)狀態(tài)更改時(shí)將顯示第二個(gè),包括顯示和隱藏,還包括方向,QuickType等。

這聽(tīng)起來(lái)就像我們并不需要keyboardWillHideNotification,如果我們有keyboardWillChangeFrameNotification,但在我的測(cè)試僅僅使用keyboardWillChangeFrameNotification是不夠的,趕上連接硬件鍵盤(pán)?,F(xiàn)在,這是一種極為罕見(jiàn)的情況,但我們還是可以肯定的!

為了將自己注冊(cè)為通知的觀察者,我們獲得了默認(rèn)通知中心的引用。然后addObserver(),我們使用self帶有四個(gè)參數(shù)的方法:應(yīng)接收通知的對(duì)象(是),應(yīng)調(diào)用的方法,我們要接收的通知以及我們要監(jiān)視的對(duì)象。我們將傳遞nil到最后一個(gè)參數(shù),表示“我們不在乎誰(shuí)發(fā)送通知”。

adjustForKeyboard()方法很復(fù)雜,但這是因?yàn)樗泻芏喙ぷ饕觥J紫?,它將接收類型為的參?shù)Notification。這將包括通知的名稱,以及Dictionary包含名為的通知特定信息userInfo。

使用鍵盤(pán)時(shí),字典中將包含一個(gè)名為UIResponder.keyboardFrameEndUserInfoKey的鍵,可以在動(dòng)畫(huà)完成后告訴我們鍵盤(pán)的框架。這將是類型NSValue,而后者又是類型CGRect。該CGRect結(jié)構(gòu)同時(shí)包含a CGPointa CGSize,因此可用于描述矩形。

Objective-C的一個(gè)怪癖是數(shù)組和字典不能包含諸如的結(jié)構(gòu)CGRect,因此Apple有一個(gè)稱為的特殊類NSValue,它充當(dāng)結(jié)構(gòu)的包裝,因此可以放入字典和數(shù)組中。這就是這里發(fā)生的事情:我們正在獲取一個(gè)NSValue對(duì)象,但是我們知道它包含一個(gè)CGRect內(nèi)部,因此我們使用其cgRectValue屬性讀取該值。

一旦我們最終拉出正確的鍵盤(pán)框架,就需要將矩形轉(zhuǎn)換為視圖的坐標(biāo)。這是因?yàn)樾D(zhuǎn)沒(méi)有考慮到框架中,所以如果用戶在風(fēng)景中,我們將翻轉(zhuǎn)寬度和高度-使用該convert()方法可以解決該問(wèn)題。

我們?cè)谠?code>adjustForKeyboard()方法中需要做的下一件事是調(diào)整文本視圖的contentInsetscrollIndicatorInsets。這兩個(gè)本質(zhì)上縮進(jìn)了文本視圖的邊緣,因此,即使其約束在視圖中仍然是邊到邊,它似乎也占據(jù)了更少的空間。

最后,我們將使文本視圖滾動(dòng),以使文本輸入光標(biāo)可見(jiàn)。如果文本視圖縮小,則現(xiàn)在將不在屏幕上,因此再次滾動(dòng)查找以保持用戶體驗(yàn)不變。

如您所見(jiàn),使用UIEdgeInsetsstruct 完成文本視圖的插入設(shè)置,該結(jié)構(gòu)需要所有四個(gè)邊緣的插入。我使用文本視圖的內(nèi)容插圖scrollIndicatorInsets來(lái)節(jié)省時(shí)間。

請(qǐng)注意,其中存在的檢查,這UIKeyboardWillHide是通過(guò)將插入項(xiàng)顯式設(shè)置為零來(lái)連接硬件鍵盤(pán)的解決方法。

實(shí)現(xiàn)效果:


QQ20200516-162120.gif
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容