iOS Keyboard Extension 開發過程遇到的坑

功能按鍵使用圖片

每一個鍵盤都須要有一個按鈕,那就是切換「下一個鍵盤」的按鈕。在系統鍵盤,這個按鈕使用了一個Emoji表情中的 🌐表情來顯示。可是對於其它的功能按鍵,卻沒有對應的Unicode編碼,所以在字體庫中也找不到對應的圖形,並且Unicode 中的這個圖形集合的展現是不統一的: 🌐⇪⌫⌨? 。ios

因此最好仍是叫UE從新設計一下這些功能按鍵的圖片吧。git

固然,你也能夠本身繪製這個按鈕了。能夠參考這個開源項目。tasty-imitation-keyboard,這個開源項目裏面的全部Function key 樣式都是本身繪製的github

Audio

要想在鍵盤播放聲音,你須要開啓鍵盤的權限。當你可能會想,至少能夠直接調用AudioServicesPlaySystemSound 這個標準函數來在鍵盤上播放聲音。可是事實上,若是用戶沒有開啓權限,那麼這個方法會卡住鍵盤,咱們能夠這樣調用:app

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
    AudioServicesPlaySystemSound(1104)
})

固然,若是你在調用這個AudioServicesPlaySystemSound 函數以前先判斷一下用戶是否開啓了權限,那麼就須要上面這樣作了。框架

另外,咱們若是隻是想播放系統默認的按鍵點擊聲音,也能夠像下面那麼作(記住,調用以前,記得先檢查用戶是否有權限,不然會卡住鍵盤):iphone

extension UIInputView: UIInputViewAudioFeedback {

    public var enableInputClicksWhenVisible: Bool { get { return true } }

    func playInputClick​() {
        UIDevice​.currentDevice​().playInputClick​()
    }
}

須要注意的是,若是你使用 AudioServicesPlaySystemSound 這個來播放聲音,那麼你在聲音播放期間是不能取消的,並且多處同時調用還會形成聲音重疊。若是你想精確控制聲音的播放,仍是使用AVPlayer框架吧。async

兼容iPad

是的,你的鍵盤必須適配全部的iOS設備,不然蘋果不會審覈經過你的APP,不過你的容器APP不必定要適配iPad。其實這是能夠理解的,假設你的容器APP不適配iPad,可是用戶仍然能夠在iPad上從AppStore 下載你的APP,此時,用戶仍是能夠從設置中添加你的鍵盤Extension,全部你的鍵盤Extension必須設配iPad。函數

同時,若是用戶在iPad上裝了iphone版的應用,而應用中又有相關依賴設備型號的業務邏輯或界面邏輯,則要當心不要只是用UIDevice類提供的方法來判斷設備,還要結合UIView的大小來判斷,不然就會可能出錯,甚至崩潰。佈局

線的繪製

若是你要繪製一個像素寬的線,則要當心,代碼裏設置UIView的frame的Width或Height爲1只是代表一個屏幕點而已,在渲染時,會轉換爲像素。性能

  1. 在1x縮放的設備上(非高清屏),1個點表明 -> 1個像素
  2. 在2x縮放的設置上(iphone 4,4s,5,5s,6,7), 1個點表明 -> 2個像素
  3. 在3x縮放的設置上(iphone 6 plus,7 plus), 1個點表明 -> 3個像素

另外注意,在ihone 6 以上的設備,都有一個放大模式,這個放大模式,其實就是屏幕的長寬點數降級:

  1. iphone 6 plus, 7 plus 放大模式: 至關於按 ihpone 6 和 7的屏幕點來顯示 2x, 1個點表明 -> 2個像素
  2. iphone 6, 7 放大模式: 至關於按 ihpone 5的屏幕點來顯示 2x, 1個點表明 -> 2個像素

因此,要得到一個像素寬的線,只須要計算

1 / (一個點對應的像素)

Size Class

蘋果在iOS 8開始,強烈推薦咱們使用Size Class來開發界面。一個這麼優雅的解決方案,在開發鍵盤擴展時,卻行不通。由於,對於鍵盤來講,Size Class 並無用。例如,在6+ 的橫屏下,鍵盤在兩個方向上都是嚴格的Compact,即便在豎屏時,這個兩個方向的layout constant 有很大的不一樣。對於iPad,鍵盤在兩個方向上都是Regular

自動佈局 AutoLayout

是的,AutoLayout是比較好的方式來佈局和約束咱們的鍵盤界面,可是若是約束不少,設置不合理,或者有多餘的約束,會比直接用layoutSubviews帶來大量的性能損耗。

虛擬機常常彈不起鍵盤

那麼快捷鍵 Command + K能夠幫到你

系統的鍵盤設置

對於第三方的鍵盤,咱們不能獲取用戶在系統的鍵盤設置內容,例如首字母自動大寫、自動更正、取消Shift功能等等設置。咱們只能要不假設一個默認值,要不就本身管理一份本身的鍵盤設置。

第三方APP與第三方鍵盤的兼容性

在某一些APP中使用第三方鍵盤,會出現一些詭異的問題,例如崩潰、鍵盤高度更新失敗(只顯示了一部分)。

若是你跟蹤UIInputViewController 的生命週期,你會發現更加詭異的問題。例如:

  1. 儘管viewWillAppear 被調用了,可是 viewDidAppear 卻沒有被調用。若是你更新鍵盤的高度操做放在 viewDidAppear 方法中,則會致使鍵盤顯示不全。幸虧這個問題目前好像只在iOS 8 中出現,iOS 9 中並無這個問題。

詭異的崩潰

沒錯,有時候你的鍵盤就會平白無故地崩潰了,有時是由於你的鍵盤啓動太慢了,有時卻沒有任何理由,對於這些崩潰,你能夠不用管。

不支持物理鍵盤

是的,若是你的iOS設備外接了物理鍵盤,那麼第三方鍵盤都是不可用的。

UIMenuController 不支持

沒錯,若是你想實現相似系統複製、粘貼的popup menu,你必須得本身實現一套了。

參考文章:

  1. http://beta-blog.archagon.net/2014/11/08/the-trials-and-tribulations-of-writing-a-3rd-party-ios-keyboard/
  2. http://norbertlindenberg.com/2014/12/developing-keyboards-for-ios/
  3. http://www.appdesignvault.com/ios-8-custom-keyboard-extension/
相關文章
相關標籤/搜索