iOS Keyboard Extension 開發過程遇到的坑


功能按鍵使用圖片

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

所以最好還是叫UE重新設計一下這些功能按鍵的圖片吧。

當然,你也可以自己繪制這個按鈕了。可以參考這個開源項目。tasty-imitation-keyboard,這個開源項目里面的所有Function key 樣式都是自己繪制的

Audio

要想在鍵盤播放聲音,你需要開啟鍵盤的權限。當你可能會想,至少可以直接調用AudioServicesPlaySystemSound 這個標准函數來在鍵盤上播放聲音。但是事實上,如果用戶沒有開啟權限,那么這個方法會卡住鍵盤,我們可以這樣調用:

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

當然,如果你在調用這個AudioServicesPlaySystemSound 函數之前先判斷一下用戶是否開啟了權限,那么就需要上面這樣做了。

另外,我們如果只是想播放系統默認的按鍵點擊聲音,也可以像下面那么做(記住,調用之前,記得先檢查用戶是否有權限,否則會卡住鍵盤):

extension UIInputView: UIInputViewAudioFeedback {

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

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

需要注意的是,如果你使用 AudioServicesPlaySystemSound 這個來播放聲音,那么你在聲音播放期間是不能取消的,而且多處同時調用還會造成聲音重疊。如果你想精確控制聲音的播放,還是使用AVPlayer框架吧。

兼容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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM