自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

iOS8自定義輸入法教程:如何創(chuàng)建第三方輸入法

移動(dòng)開發(fā) iOS
iOS8帶來了很多很酷的功能,其中一個(gè)就是增加第三方輸入法作為應(yīng)用程序擴(kuò)展。我們應(yīng)當(dāng)重視這個(gè)時(shí)刻,因?yàn)閼?yīng)用程序擴(kuò)展開辟了一個(gè)全新的應(yīng)用程序種類以及付費(fèi)操作。憑借著在應(yīng)用商店中數(shù)百萬的應(yīng)用程序,開發(fā)者和用戶將迎來全新的一天。

iOS8帶來了很多很酷的功能,其中一個(gè)就是增加第三方輸入法作為應(yīng)用程序擴(kuò)展。我們應(yīng)當(dāng)重視這個(gè)時(shí)刻,因?yàn)閼?yīng)用程序擴(kuò)展開辟了一個(gè)全新的應(yīng)用程序種類以及付費(fèi)操作。憑借著在應(yīng)用商店中數(shù)百萬的應(yīng)用程序,開發(fā)者和用戶將迎來全新的一天。

在本帖中,我將向您展示如何為您的應(yīng)用程序創(chuàng)建一個(gè)可進(jìn)行全系統(tǒng)輸入法操作的第三方輸入法。

本教程將用Swift來完成。這是我的***個(gè)真正用Swift語言完成的項(xiàng)目,我對(duì)其十分喜愛?,F(xiàn)在,讓我們直接研究如何創(chuàng)建一個(gè)第三方輸入法。

首先,我先向大家展示一下我們要搭建的輸入法的最終效果圖。輸入法將能夠在文本框中輸入、刪除文字以及實(shí)現(xiàn)其他基本功能。諸如上下文預(yù)測、詞典等更為高級(jí)的功能超出了本教程的范圍。

創(chuàng)建Xcode項(xiàng)目

 

打開Xcode 6并創(chuàng)建一個(gè)新項(xiàng)目。File->New->Project

 

 

給工程命名為CustomKeyboardSample并在恰當(dāng)?shù)奈恢帽4?。這是我們的主項(xiàng)目,但是我們還需要添加擴(kuò)展。

 

 

現(xiàn)在,讓我們往項(xiàng)目中添加一個(gè)Text Field。打開Main.Storyboard文件然后在屏幕上的視圖控制器上拖放一個(gè)UITextField控件。

 

這是我們用來測試輸入的地方。現(xiàn)在是時(shí)候來添加擴(kuò)展了。

點(diǎn)擊File-> New -> Target,選擇在iOS/Application Extension列表中的自定義輸入法(Custom Keyboard)。給該擴(kuò)展命名為CustomKeyboard并選擇Swift編程語言。

添加擴(kuò)展

現(xiàn)在你應(yīng)該有一個(gè)名為CustomKeyboard的新目標(biāo)文件夾,其中有一個(gè)名為KeyboardViewController.swift文件。 Xcode中已經(jīng)為我們?cè)黾恿艘恍┏跏即a和這個(gè)鍵盤應(yīng)該可以運(yùn)行了(盡管沒有什么功能)。

 

 

現(xiàn)在,您可以嘗試運(yùn)行CustomKeyboardSample,并嘗試新的輸入法。

 

 

當(dāng)你點(diǎn)擊文本框的時(shí)候,系統(tǒng)鍵盤會(huì)顯示出來。我們可以使用底排的地球圖標(biāo)來切換輸入法,但是我們只有安裝我們的新鍵盤后,這個(gè)圖標(biāo)才會(huì)顯示出來。

 

 

轉(zhuǎn)到主屏幕(點(diǎn)擊菜單欄,Hardware->Home)。打開設(shè)置并轉(zhuǎn)到通用->鍵盤->鍵盤。點(diǎn)擊“添加新鍵盤”,然后選擇CustomKeyboard。 打開開關(guān)來啟用它并同意警告信息。

 

 

點(diǎn)擊完成,您可以準(zhǔn)備好開始了!

 

 

如果在模擬器上再次運(yùn)行該應(yīng)用程序,那么就可以切換輸入法。點(diǎn)擊地球圖標(biāo),直到你看到只有“Next Keyboard”按鈕的鍵盤。

 

 

現(xiàn)在是時(shí)候開始添加輸入法的按鍵了。

 

 

打開文件KeyboardViewController.h。在這個(gè)文件中,你會(huì)看到一個(gè)類KeyboardViewController繼承自UIInputViewController。這是管理視圖的鍵盤類。我們可以向包含視圖中添加按鈕,它會(huì)在鍵盤中顯示出來。

 

添加一個(gè)名為createButton的函數(shù)

 

  1. func createButtonWithTitle(title: String) -> UIButton {  
  2.     let button = UIButton.buttonWithType(.System) as UIButton  
  3.     button.frame = CGRectMake(002020)  
  4.     button.setTitle(title, forState: .Normal)  
  5.     button.sizeToFit()  
  6.     button.titleLabel.font = UIFont.systemFontOfSize(15)  
  7.     button.setTranslatesAutoresizingMaskIntoConstraints(false)  
  8.     button.backgroundColor = UIColor(white: 1.0, alpha: 1.0)  
  9.     button.setTitleColor(UIColor.darkGrayColor(), forState: .Normal)  
  10.     button.addTarget(self, action: "didTapButton:", forControlEvents: .TouchUpInside)  
  11.     return button  
  12.     }  

在上面的代碼中,我們以編程的方式來添加一個(gè)按鈕,并設(shè)置其屬性。我們可以用nib文件來實(shí)現(xiàn),但我們將不得不管理如此之多的按鈕。因此這是一個(gè)更好的選擇。

 

 

該代碼會(huì)調(diào)用一個(gè)名為didTapButton的響應(yīng)按鈕被按下的方法。現(xiàn)在讓我們添加一個(gè)方法。

 

  1. func didTapButton(sender: AnyObject?) {  
  2.     let button = sender as UIButton  
  3.     let title = button.titleForState(.Normal)  
  4.     var proxy = textDocumentProxy as UITextDocumentProxy  
  5.   
  6.     proxy.insertText(title)  
  7.     }  

在上面的方法中,我們用swift實(shí)現(xiàn)了對(duì)一個(gè)按鈕事件的處理。AnyObject類型就像是在Objective-C中的ID的對(duì)象。我們給UIButton放置了一個(gè)傳送器,然后得到該按鈕的標(biāo)題文字,這些文字是我們要在文本框中要輸入的文本文字。

 

 

要使用輸入法輸入文本,我們使用textDocumentProxy對(duì)象,并調(diào)用insertText方法。

 

 

接下來的一步是添加一個(gè)按鈕到我們的鍵盤視圖。在viewDidLoad方法下面加入兩行代碼。您可以在viewDidLoad和textDidChange方法中刪除自動(dòng)生成的代碼。

 

override func viewDidLoad() {

 

super.viewDidLoad()

 

 

let button = createButtonWithTitle("A")

 

self.view.addSubview(button)

 

}

 

增加了標(biāo)題為“A”到輸入法的按鈕。這是我們的關(guān)鍵所在。

 

 

現(xiàn)在,運(yùn)行應(yīng)用程序,然后點(diǎn)擊文本框,你應(yīng)該可以看到鍵盤的”A”鍵。 (你可能需要切換鍵盤)。

 

 

點(diǎn)擊這個(gè)按鈕,看看會(huì)發(fā)生什么......看!我們已經(jīng)有了文字A!

 

 

好吧,讓我們添加更多的按鍵,讓這個(gè)小子看起來像一個(gè)真正的輸入法。

 

 

讓我們修改我們?cè)趘iewDidLoad方法中加入的代碼。

 

 

  1. override func viewDidLoad() {  
  2.    super.viewDidLoad()  
  3.   
  4.    let buttonTitles = ["Q""W""E""R""T""Y""U""I""O""P"]  
  5.    var buttons = UIButton[]()  
  6.    var keyboardRowView = UIView(frame: CGRectMake(0032050))  
  7.   
  8.    for buttonTitle in buttonTitles{  
  9.        let button = createButtonWithTitle(buttonTitle)  
  10.        buttons.append(button)  
  11.        keyboardRowView.addSubview(button)  
  12.        }  
  13.   
  14.    self.view.addSubview(keyboardRowView)    
現(xiàn)在有了這個(gè)新的代碼,我們創(chuàng)建了一個(gè)包含按鍵標(biāo)題的數(shù)組,同時(shí)我們也創(chuàng)造了包含這些按鍵的列表。每個(gè)按鍵都被添加到一個(gè)數(shù)組和一個(gè)UIView中,這將是我們的***排鍵列。然后向主鍵盤圖中添加該視圖。 如果你運(yùn)行這個(gè)程序,你可能只看到了P鍵,因?yàn)樗械陌粹o都在同一位置。我們需要以編程方式添加一些約束,使他們能夠在一排對(duì)齊。 因此,我們將創(chuàng)建一個(gè)新的函數(shù)來創(chuàng)建約束。
  1. func addIndividualButtonConstraints(buttons: UIButton[], mainView: UIView){  
  2.     for (index, button) in enumerate(buttons) {  
  3.   
  4.     var topConstraint = NSLayoutConstraint(item: button, attribute: .Top, relatedBy: .Equal, toItem: mainView, attribute: .Top, multiplier: 1.0, constant: 1)  
  5.   
  6.     var bottomConstraint = NSLayoutConstraint(item: button, attribute: .Bottom, relatedBy: .Equal, toItem: mainView, attribute: .Bottom, multiplier: 1.0, constant: -1)  
  7.   
  8.     var rightConstraint : NSLayoutConstraint!  
  9.   
  10.     if index == buttons.count - 1 {  
  11.   
  12.         rightConstraint = NSLayoutConstraint(item: button, attribute: .Right, relatedBy: .Equal, toItem: mainView, attribute: .Right, multiplier: 1.0, constant: -1)  
  13.   
  14.     }else{  
  15.   
  16.     let nextButton = buttons[index+1]  
  17.     rightConstraint = NSLayoutConstraint(item: button, attribute: .Right, relatedBy: .Equal, toItem: nextButton, attribute: .Left, multiplier: 1.0, constant: -1)  
  18.             }  
  19.   
  20.     var leftConstraint : NSLayoutConstraint!  
  21.   
  22.     if index == 0 {  
  23.   
  24.         leftConstraint = NSLayoutConstraint(item: button, attribute: .Left, relatedBy: .Equal, toItem: mainView, attribute: .Left, multiplier: 1.0, constant: 1)  
  25.   
  26.     }else{  
  27.   
  28.         let prevtButton = buttons[index-1]  
  29.         leftConstraint = NSLayoutConstraint(item: button, attribute: .Left, relatedBy: .Equal, toItem: prevtButton, attribute: .Right, multiplier: 1.0, constant: 1)  
  30.   
  31.         let firstButton = buttons[0]  
  32.         var widthConstraint = NSLayoutConstraint(item: firstButton, attribute: .Width, relatedBy: .Equal, toItem: button, attribute: .Width, multiplier: 1.0, constant: 0)  
  33.   
  34.         mainView.addConstraint(widthConstraint)  
  35.     }  
  36.   
  37.     mainView.addConstraints([topConstraint, bottomConstraint, rightConstraint, leftConstraint])  
  38.     }  
  39. }  

這是一個(gè)很長的代碼,不是嗎?有了AutoLayout,你不能真正建立起它并且你需要立即添加所有約束,否則它將不工作。上面代碼的主要工作是添加邊界為1px的約束,這些約束將添加到每個(gè)按鍵的頂部和底部。它也增加了左右兩邊邊界為1px的約束,添加到相鄰鍵的左邊和右邊(或添加到行視圖,如果它是該行中的***個(gè)或***一個(gè)鍵的話)。

 

 

如果在viewDidLoad中添加調(diào)用上面函數(shù)的功能,我們應(yīng)該可以看到新的排按鍵顯示出來。

 

現(xiàn)在,這看起來更像是一個(gè)輸入法了。接下來的步驟是添加輸入法的其他行。要做到這一點(diǎn),讓我們做一些快速重構(gòu)。創(chuàng)建并實(shí)現(xiàn)添加每行按鍵的新方法。

  1. func createRowOfButtons(buttonTitles: NSString[]) -> UIView {  
  2.   
  3.     var buttons = UIButton[]()  
  4.     var keyboardRowView = UIView(frame: CGRectMake(0032050))  
  5.   
  6.     for buttonTitle in buttonTitles{  
  7.         let button = createButtonWithTitle(buttonTitle)  
  8.         buttons.append(button)  
  9.         keyboardRowView.addSubview(button)  
  10.     }  
  11.   
  12.     addIndividualButtonConstraints(buttons, mainView: keyboardRowView)  
  13.   
  14.     return keyboardRowView  
  15. }  

我們已經(jīng)基本將viewDidLoad中的代碼提取到它自己的方法中。這種新的方法將標(biāo)題文字存放在數(shù)列中,并返回包含該行所有按鈕的視圖?,F(xiàn)在,我們可以在任何一個(gè)我們想要添加的代碼中調(diào)用這段代碼。

 

 

因此,我們的新vieDidLoad方法是這樣的:

 

  1. override func viewDidLoad() {  
  2.     super.viewDidLoad()  
  3.   
  4.     let buttonTitles1 = ["Q""W""E""R""T""Y""U""I""O""P"]  
  5.     let buttonTitles2 = ["A""S""D""F""G""H""J""K""L"]  
  6.     let buttonTitles3 = ["CP""Z""X""C""V""B""N""M""BP"]  
  7.     let buttonTitles4 = ["CHG""SPACE""RETURN"]  
  8.   
  9.     var row1 = createRowOfButtons(buttonTitles1)  
  10.     var row2 = createRowOfButtons(buttonTitles2)  
  11.     var row3 = createRowOfButtons(buttonTitles3)  
  12.     var row4 = createRowOfButtons(buttonTitles4)  
  13.   
  14.     self.view.addSubview(row1)  
  15.     self.view.addSubview(row2)  
  16.     self.view.addSubview(row3)  
  17.     self.view.addSubview(row4)  
  18.   
  19. }  

在上面的代碼中,我們已經(jīng)加入4行鍵,然后加入這些按鍵,后者又被添加到主視圖中的行中。

我們現(xiàn)在可以運(yùn)行代碼,但你只能看到***一排,因?yàn)樗麄兌荚谕晃恢谩?我們需要添加一些自動(dòng)布局的約束。

  1. func addConstraintsToInputView(inputView: UIView, rowViews: UIView[]){  
  2.   
  3.     for (index, rowView) in enumerate(rowViews) {  
  4.         var rightSideConstraint = NSLayoutConstraint(item: rowView, attribute: .Right, relatedBy: .Equal, toItem: inputView, attribute: .Right, multiplier: 1.0, constant: -1)  
  5.   
  6.         var leftConstraint = NSLayoutConstraint(item: rowView, attribute: .Left, relatedBy: .Equal, toItem: inputView, attribute: .Left, multiplier: 1.0, constant: 1)  
  7.   
  8.         inputView.addConstraints([leftConstraint, rightSideConstraint])  
  9.   
  10.         var topConstraint: NSLayoutConstraint  
  11.   
  12.         if index == 0 {  
  13.             topConstraint = NSLayoutConstraint(item: rowView, attribute: .Top, relatedBy: .Equal, toItem: inputView, attribute: .Top, multiplier: 1.0, constant: 0)  
  14.   
  15.         }else{  
  16.   
  17.             let prevRow = rowViews[index-1]  
  18.             topConstraint = NSLayoutConstraint(item: rowView, attribute: .Top, relatedBy: .Equal, toItem: prevRow, attribute: .Bottom, multiplier: 1.0, constant: 0)  
  19.   
  20.             let firstRow = rowViews[0]  
  21.             var heightConstraint = NSLayoutConstraint(item: firstRow, attribute: .Height, relatedBy: .Equal, toItem: rowView, attribute: .Height, multiplier: 1.0, constant: 0)  
  22.   
  23.             inputView.addConstraint(heightConstraint)  
  24.         }  
  25.     inputView.addConstraint(topConstraint)  
  26.   
  27.     var bottomConstraint: NSLayoutConstraint  
  28.   
  29.     if index == rowViews.count - 1 {  
  30.         bottomConstraint = NSLayoutConstraint(item: rowView, attribute: .Bottom, relatedBy: .Equal, toItem: inputView, attribute: .Bottom, multiplier: 1.0, constant: 0)  
  31.   
  32.     }else{  
  33.   
  34.         let nextRow = rowViews[index+1]  
  35.         bottomConstraint = NSLayoutConstraint(item: rowView, attribute: .Bottom, relatedBy: .Equal, toItem: nextRow, attribute: .Top, multiplier: 1.0, constant: 0)  
  36.     }  
  37.   
  38.     inputView.addConstraint(bottomConstraint)  
  39.     }  
  40. }  

這種新方法做了類似的功能,我們?cè)黾恿?**的自動(dòng)布局代碼。它增加了相對(duì)于主視圖向行的左右兩邊以及下面的1px的約束和添加每一行和和它上面行之間的0px約束。

現(xiàn)在,我們需要從我們的viewDidLoad方法中調(diào)用這段代碼。

  1. override func viewDidLoad() {  
  2.     super.viewDidLoad()  
  3.   
  4.     let buttonTitles1 = ["Q""W""E""R""T""Y""U""I""O""P"]  
  5.     let buttonTitles2 = ["A""S""D""F""G""H""J""K""L"]  
  6.     let buttonTitles3 = ["CP""Z""X""C""V""B""N""M""BP"]  
  7.     let buttonTitles4 = ["CHG""SPACE""RETURN"]  
  8.   
  9.     var row1 = createRowOfButtons(buttonTitles1)  
  10.     var row2 = createRowOfButtons(buttonTitles2)  
  11.     var row3 = createRowOfButtons(buttonTitles3)  
  12.     var row4 = createRowOfButtons(buttonTitles4)  
  13.   
  14.     self.view.addSubview(row1)  
  15.     self.view.addSubview(row2)  
  16.     self.view.addSubview(row3)  
  17.     self.view.addSubview(row4)  
  18.   
  19.     row1.setTranslatesAutoresizingMaskIntoConstraints(false)  
  20.     row2.setTranslatesAutoresizingMaskIntoConstraints(false)  
  21.     row3.setTranslatesAutoresizingMaskIntoConstraints(false)  
  22.     row4.setTranslatesAutoresizingMaskIntoConstraints(false)  
  23.   
  24.     addConstraintsToInputView(self.view, rowViews: [row1, row2, row3, row4])  
  25. }  

這是我們新的viewDidLoad函數(shù)。你會(huì)看到,我們把每一行的TranslatesAutoresizingMaskIntoConstraints設(shè)為了false。這是為了確保更好的使用自動(dòng)布局的方法,而不是使用約束的布局。

 

 

現(xiàn)在,如果你運(yùn)行應(yīng)用程序,你會(huì)看到輸入法均能正常自如地布局。您可以點(diǎn)擊所有的按鈕,看看它們輸入到文本框中。

 

還有一個(gè)小問題,非文本鍵無法正常工作(例如,退格鍵,空格鍵)。

 

 

為了解決這個(gè)問題,我們需要改變我們的didTapButton方法來添加響應(yīng)這些鍵的正確方法。

 

  1. func didTapButton(sender: AnyObject?) {  
  2.   
  3.     let button = sender as UIButton  
  4.     let title = button.titleForState(.Normal) as String  
  5.     var proxy = textDocumentProxy as UITextDocumentProxy  
  6.   
  7.     proxy.insertText(title)  
  8.   
  9.     switch title {  
  10.     case "BP" :  
  11.         proxy.deleteBackward()  
  12.     case "RETURN" :  
  13.         proxy.insertText("\n")  
  14.     case "SPACE" :  
  15.         proxy.insertText(" ")  
  16.     case "CHG" :  
  17.         self.advanceToNextInputMode()  
  18.     default :  
  19.         proxy.insertText(title)  
  20.     }  
  21. }  

這里用switch語句來對(duì)按下的鍵進(jìn)行識(shí)別處理。退格鍵調(diào)用代理上的deleteBackward方法,空格鍵插入一個(gè)空格和CHG鍵改變輸入法或者系統(tǒng)輸入法或安裝下一個(gè)輸入法。

 

 

下一步是什么?

 

教程就到這里,本教程就如何創(chuàng)建一個(gè)基本的自定義鍵盤進(jìn)行了一個(gè)粗略的講解。你的作業(yè)是這個(gè)進(jìn)一步優(yōu)化,看看您是否可以添加更高級(jí)的功能,如使用Caps Lock鍵添加大寫字母,切換到數(shù)字/符號(hào)鍵盤方案等。

 

本文鏈接:http://www.cocoachina.com/ios/20140922/9706.html

責(zé)任編輯:chenqingxiang 來源: cocoachina
相關(guān)推薦

2021-08-04 16:36:00

Windows 10Windows微軟

2014-12-29 10:05:24

iOS 8越獄插件

2010-01-11 10:09:14

Ubuntulinux輸入法設(shè)置

2010-01-08 16:50:51

Ubuntu SCIM

2010-06-08 18:50:30

OpenSUSE 輸入

2012-02-15 11:14:21

搜狗輸入法

2021-10-15 22:17:08

Windows 10Windows微軟

2021-04-20 08:30:23

微信微信輸入法張小龍

2011-09-15 09:34:48

ubuntu輸入法

2021-11-06 23:04:10

Windows 10Windows微軟

2013-01-10 11:27:58

Android輸入法分析報(bào)告

2010-02-07 14:25:47

Ubuntu SCIM

2010-03-25 13:19:17

云計(jì)算

2009-08-31 16:29:21

C#控制輸入法

2013-09-18 10:44:01

搜狗輸入法詞語

2023-09-09 07:08:37

百度輸入法AI

2021-11-11 23:00:50

Windows 10Windows微軟

2014-12-10 10:47:20

iOS 8.1.1iPadiPhone
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)