iOS keyboard 高度監(jiān)聽

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

實現(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)
    }
}

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

使用鍵盤時休讳,我們關(guān)注的通知是keyboardWillHideNotificationkeyboardWillChangeFrameNotification主届。當(dāng)鍵盤完成隱藏時赵哲,將發(fā)送第一個,而在發(fā)生任何鍵盤狀態(tài)更改時將顯示第二個君丁,包括顯示和隱藏枫夺,還包括方向,QuickType等绘闷。

這聽起來就像我們并不需要keyboardWillHideNotification橡庞,如果我們有keyboardWillChangeFrameNotification,但在我的測試僅僅使用keyboardWillChangeFrameNotification是不夠的簸喂,趕上連接硬件鍵盤”兴溃現(xiàn)在,這是一種極為罕見的情況喻鳄,但我們還是可以肯定的扼倘!

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

adjustForKeyboard()方法很復(fù)雜稠诲,但這是因為它有很多工作要做侦鹏。首先,它將接收類型為的參數(shù)Notification臀叙。這將包括通知的名稱略水,以及Dictionary包含名為的通知特定信息userInfo

使用鍵盤時劝萤,字典中將包含一個名為UIResponder.keyboardFrameEndUserInfoKey的鍵渊涝,可以在動畫完成后告訴我們鍵盤的框架。這將是類型NSValue床嫌,而后者又是類型CGRect跨释。該CGRect結(jié)構(gòu)同時包含a CGPointa CGSize,因此可用于描述矩形厌处。

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

一旦我們最終拉出正確的鍵盤框架,就需要將矩形轉(zhuǎn)換為視圖的坐標(biāo)凶伙。這是因為旋轉(zhuǎn)沒有考慮到框架中郭毕,所以如果用戶在風(fēng)景中,我們將翻轉(zhuǎn)寬度和高度-使用該convert()方法可以解決該問題函荣。

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

最后金拒,我們將使文本視圖滾動兽肤,以使文本輸入光標(biāo)可見套腹。如果文本視圖縮小,則現(xiàn)在將不在屏幕上资铡,因此再次滾動查找以保持用戶體驗不變电禀。

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

請注意店雅,其中存在的檢查政基,這UIKeyboardWillHide是通過將插入項顯式設(shè)置為零來連接硬件鍵盤的解決方法。

實現(xiàn)效果:


QQ20200516-162120.gif
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闹啦,一起剝皮案震驚了整個濱河市腋么,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌亥揖,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件圣勒,死亡現(xiàn)場離奇詭異费变,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)圣贸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門挚歧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吁峻,你說我怎么就攤上這事滑负。” “怎么了用含?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵矮慕,是天一觀的道長。 經(jīng)常有香客問我啄骇,道長痴鳄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任缸夹,我火速辦了婚禮痪寻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘虽惭。我一直安慰自己橡类,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布芽唇。 她就那樣靜靜地躺著神僵,像睡著了一般碰酝。 火紅的嫁衣襯著肌膚如雪族购。 梳的紋絲不亂的頭發(fā)上辞做,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機(jī)與錄音颁虐,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛虾标,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播灌砖,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼璧函,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了基显?” 一聲冷哼從身側(cè)響起蘸吓,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撩幽,沒想到半個月后库继,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡窜醉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年宪萄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片榨惰。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡拜英,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出琅催,到底是詐尸還是另有隱情居凶,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布藤抡,位于F島的核電站侠碧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏缠黍。R本人自食惡果不足惜舆床,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嫁佳。 院中可真熱鬧挨队,春花似錦、人聲如沸蒿往。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瓤漏。三九已至腾夯,卻和暖如春颊埃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蝶俱。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工班利, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人榨呆。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓罗标,卻偏偏與公主長得像,于是被迫代替她去往敵國和親积蜻。 傳聞我的和親對象是個殘疾皇子闯割,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355