成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

iOS8自定義輸入法教程:如何創建第三方輸入法

移動開發 iOS
iOS8帶來了很多很酷的功能,其中一個就是增加第三方輸入法作為應用程序擴展。我們應當重視這個時刻,因為應用程序擴展開辟了一個全新的應用程序種類以及付費操作。憑借著在應用商店中數百萬的應用程序,開發者和用戶將迎來全新的一天。

iOS8帶來了很多很酷的功能,其中一個就是增加第三方輸入法作為應用程序擴展。我們應當重視這個時刻,因為應用程序擴展開辟了一個全新的應用程序種類以及付費操作。憑借著在應用商店中數百萬的應用程序,開發者和用戶將迎來全新的一天。

在本帖中,我將向您展示如何為您的應用程序創建一個可進行全系統輸入法操作的第三方輸入法。

本教程將用Swift來完成。這是我的***個真正用Swift語言完成的項目,我對其十分喜愛。現在,讓我們直接研究如何創建一個第三方輸入法。

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

創建Xcode項目

 

打開Xcode 6并創建一個新項目。File->New->Project

 

 

給工程命名為CustomKeyboardSample并在恰當的位置保存。這是我們的主項目,但是我們還需要添加擴展。

 

 

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

 

這是我們用來測試輸入的地方。現在是時候來添加擴展了。

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

添加擴展

現在你應該有一個名為CustomKeyboard的新目標文件夾,其中有一個名為KeyboardViewController.swift文件。 Xcode中已經為我們增加了一些初始代碼和這個鍵盤應該可以運行了(盡管沒有什么功能)。

 

 

現在,您可以嘗試運行CustomKeyboardSample,并嘗試新的輸入法。

 

 

當你點擊文本框的時候,系統鍵盤會顯示出來。我們可以使用底排的地球圖標來切換輸入法,但是我們只有安裝我們的新鍵盤后,這個圖標才會顯示出來。

 

 

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

 

 

點擊完成,您可以準備好開始了!

 

 

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

 

 

現在是時候開始添加輸入法的按鍵了。

 

 

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

 

添加一個名為createButton的函數

 

  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.     }  

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

 

 

該代碼會調用一個名為didTapButton的響應按鈕被按下的方法。現在讓我們添加一個方法。

 

  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實現了對一個按鈕事件的處理。AnyObject類型就像是在Objective-C中的ID的對象。我們給UIButton放置了一個傳送器,然后得到該按鈕的標題文字,這些文字是我們要在文本框中要輸入的文本文字。

 

 

要使用輸入法輸入文本,我們使用textDocumentProxy對象,并調用insertText方法。

 

 

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

 

override func viewDidLoad() {

 

super.viewDidLoad()

 

 

let button = createButtonWithTitle("A")

 

self.view.addSubview(button)

 

}

 

增加了標題為“A”到輸入法的按鈕。這是我們的關鍵所在。

 

 

現在,運行應用程序,然后點擊文本框,你應該可以看到鍵盤的”A”鍵。 (你可能需要切換鍵盤)。

 

 

點擊這個按鈕,看看會發生什么......看!我們已經有了文字A!

 

 

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

 

 

讓我們修改我們在viewDidLoad方法中加入的代碼。

 

 

  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)    
現在有了這個新的代碼,我們創建了一個包含按鍵標題的數組,同時我們也創造了包含這些按鍵的列表。每個按鍵都被添加到一個數組和一個UIView中,這將是我們的***排鍵列。然后向主鍵盤圖中添加該視圖。 如果你運行這個程序,你可能只看到了P鍵,因為所有的按鈕都在同一位置。我們需要以編程方式添加一些約束,使他們能夠在一排對齊。 因此,我們將創建一個新的函數來創建約束。
  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. }  

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

 

 

如果在viewDidLoad中添加調用上面函數的功能,我們應該可以看到新的排按鍵顯示出來。

 

現在,這看起來更像是一個輸入法了。接下來的步驟是添加輸入法的其他行。要做到這一點,讓我們做一些快速重構。創建并實現添加每行按鍵的新方法。

  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. }  

我們已經基本將viewDidLoad中的代碼提取到它自己的方法中。這種新的方法將標題文字存放在數列中,并返回包含該行所有按鈕的視圖。現在,我們可以在任何一個我們想要添加的代碼中調用這段代碼。

 

 

因此,我們的新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. }  

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

我們現在可以運行代碼,但你只能看到***一排,因為他們都在同一位置。 我們需要添加一些自動布局的約束。

  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. }  

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

現在,我們需要從我們的viewDidLoad方法中調用這段代碼。

  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函數。你會看到,我們把每一行的TranslatesAutoresizingMaskIntoConstraints設為了false。這是為了確保更好的使用自動布局的方法,而不是使用約束的布局。

 

 

現在,如果你運行應用程序,你會看到輸入法均能正常自如地布局。您可以點擊所有的按鈕,看看它們輸入到文本框中。

 

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

 

 

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

 

  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語句來對按下的鍵進行識別處理。退格鍵調用代理上的deleteBackward方法,空格鍵插入一個空格和CHG鍵改變輸入法或者系統輸入法或安裝下一個輸入法。

 

 

下一步是什么?

 

教程就到這里,本教程就如何創建一個基本的自定義鍵盤進行了一個粗略的講解。你的作業是這個進一步優化,看看您是否可以添加更高級的功能,如使用Caps Lock鍵添加大寫字母,切換到數字/符號鍵盤方案等。

 

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

責任編輯:chenqingxiang 來源: cocoachina
相關推薦

2021-08-04 16:36:00

Windows 10Windows微軟

2014-12-29 10:05:24

iOS 8越獄插件

2010-01-08 16:50:51

Ubuntu SCIM

2010-06-08 18:50:30

OpenSUSE 輸入

2012-02-15 11:14:21

搜狗輸入法

2010-01-11 10:09:14

Ubuntulinux輸入法設置

2021-10-15 22:17:08

Windows 10Windows微軟

2011-09-15 09:34:48

ubuntu輸入法

2021-04-20 08:30:23

微信微信輸入法張小龍

2021-11-06 23:04:10

Windows 10Windows微軟

2013-01-10 11:27:58

Android輸入法分析報告

2010-03-25 13:19:17

云計算

2010-02-07 14:25:47

Ubuntu SCIM

2013-09-18 10:44:01

搜狗輸入法詞語

2009-08-31 16:29:21

C#控制輸入法

2023-09-09 07:08:37

百度輸入法AI

2011-04-29 11:05:57

搜狗手機輸入法

2021-11-11 23:00:50

Windows 10Windows微軟
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人免费高清 | 精品伦精品一区二区三区视频 | 国产成人福利在线观看 | 成人免费视频网站在线观看 | 精品国产一区二区三区免费 | 国产日韩一区二区三区 | 国产精品成人一区二区三区 | 91麻豆精品国产91久久久更新资源速度超快 | 欧美大片黄 | 波多野结衣二区 | 日韩电影一区二区三区 | 欧美日韩视频在线播放 | 一级做a爰片性色毛片16 | 欧美精品久久久久 | 亚洲激精日韩激精欧美精品 | 女女爱爱视频 | 成人av在线播放 | 国产一二三区精品视频 | 亚洲一区二区三区视频免费观看 | 婷婷五月色综合香五月 | 日韩高清一区 | 亚洲区一区二 | 91极品尤物在线播放国产 | 久久国产电影 | 亚洲视频在线观看 | 日韩小视频在线 | 成人在线观看免费观看 | 亚洲国产精品人人爽夜夜爽 | 日日想夜夜操 | 欧美激情精品久久久久久变态 | 国产一区二区三区久久久久久久久 | 99这里只有精品 | 69福利影院 | 日韩av在线不卡 | 天天艹天天干天天 | 久久精品青青大伊人av | 伊人99 | 亚洲精品大片 | 日日夜夜天天 | 国产高清免费视频 | av网站在线播放 |