我会复习一下有关键盘扩展的内容,然后通过使用iOS 8中的新应用扩展API的设计一个摩斯码的输入法。完成这个教程大约需要花费20分钟。 完整代码
 
概览
通过使用自定义输入法替换系统输入法,用户可以实现一些特别的功能。例如一个特别新颖的输入方式,或输入iOS原生并不支持的语言。自定义输入法的基本功能很简单:通过点击、手势,或者其他输入事件,然后通过一个未分类的 NSString 对象在当前文本输入对象的文本插入点插入文字。
当用户选择了某个输入法后,当应用打开时,它将会变为默认的输入法。因此,任意输入法都应该允许用户切换到另一个输入法。
对于每一个自定义输入法,有两个很重要的点:
1、信任: 你的自定义输入法能够让你访问用户输入的所有内容,因此你和你的用户之间的信任非常重要。
2、一个“下一个输入法”选项: 兼容能够让用户切换至另一个输入法必须成为每个自定义输入法界面的一部分。你必须在你的界面中中提供。
注意:如果你只是想在系统键盘中加上一些按钮,那么你应该研究一下  自定义数据输入视图。
自定义输入法所不能实现的
有一些输入对象是自定义输入法不能被使用的情况:安全字段(例如密码),电话号码对象(就像联系人应用中的号码字段)。
你的自定义输入法不能访问输入框的视图层级,它也不能控制光标和选择文本。
同样,自定义输入法不能在顶行之外显示任何内容(就像系统键盘当你在后面的行上长按一个键时)。
沙盒
默认情况下,自定义输入法并没有网络访问,也不能和容纳它的应用共享文件。如果想实现这些功能,必须在Info.plist文件中将RequestOpenAccess布尔值至YES。做了这个之后,会扩展自定义输入法的沙盒,就像在  建立和维护用户信任 提到的那样。
如果你确实需要申请访问权限,你的输入法将获得以下权限,每一个都会有相应的责任:
1.访问位置服务和地址本数据库,每一个都需在第一次访问时获得授权。
2.可选择与容纳该输入法的应用的共享容器,使得在应用中可以定制词汇表。
3.能够将输入的字符和其他输入事件上传至服务器进行处理。
4.访问iCloud,例如,能够确保输入法的设置以及你的自动修正词汇能够在所有用户设备上同步。
5.通过包含还输入法的应用,能够访问Game Center和应用内购买。
6.能够和受控应用进行协同,如果你使用来设计该键盘以支持移动设备管理(MDM)
如果你确实要打开这些权限,确保你阅读” 为用户信任而设计“这篇文章,它介绍了你的责任以集如何尊重和保护用户的数据。
顶层设计
接下来的图形展示了在运行的输入法下有哪些重要的元素,同时展示了在一个典型的开发流程中,他们的位置。在大部分情况下,我们通过一个应用来容纳这个输入法扩展,一个UIInputViewController来控制这个键盘并针对用户事件给予反馈。
自定义的输入法模板包含一个 UIInputViewController 的子类,这个就是你的输入法的主要视图控制器。让我们看一下他的接口来熟悉一下是如何实现的:
 
  1. class UIInputViewController : UIViewController, UITextInputDelegate, NSObjectProtocol {
  2. var inputView: UIInputView!
  3. var textDocumentProxy: NSObject! { get }
  4. func dismissKeyboard()
  5. func advanceToNextInputMode()
  6. // This will not provide a complete repository of a language's vocabulary.
  7. // It is solely intended to supplement existing lexicons.
  8. func requestSupplementaryLexiconWithCompletion(completionHandler: ((UILexicon!) -> Void)!)
  9. }
UIInputViewController 支持 UITextInputDelegate 协议,当文本区或者文本选项区变化时,通过 selectionWillChange,selectionDidChange,textWillChange 和 textDidChange事件来实现。

设计一个摩斯码输入法
我们会设计实现一个简单的输入法,可以输入 点 和 划,改变了键盘结构,删除字符然后隐藏自己。这个范例通过代码来生成的用户界面。当然,我们同样也可以使用Nib文件来生成界面-这个会在教程的末尾涉及。加载Nib文件会对性能有负面影响。
创建一个工程
打开Xcode6 ,创建一个“Single Page Application”,然后选择Swift为编程语言。
添加一个文本区域
打开Main.storyboard然后拖拽一个文本区域从组件库里。我们会使用这个来测试我们设计的键盘。
将这个文本区域居中,然后添加必要的contraints。
Hint: 如果你调用 textField.becomeFirstResponder()在viewDidLoad ,这个键盘会自动在应用打开时弹出。
添加这个键盘扩展
从导航器中选择这个项目文件,然后通过按+按钮添加一个新的target。
选择Application Extension然后使用Custom Keyboard模板,命名它为MorseCodeKeyboard。
这会创建一个名为 MorseCodeKeyboard 新文件夹,包括2个文件 KeyboardViewController.swift 和 Info.Plist。
接下来
打开 KeyboardViewController.swift,为了在不同的键盘之间进行切换,这个键盘模板文件会有一个按钮。在 viewDidLoad 方法中放入一个新的方法,命名为 addNextKeyboardButton。
 
  1. func addNextKeyboardButton() {
  2. self.nextKeyboardButton = UIButton.buttonWithType(.System) as UIButton
  3. ...
  4. var nextKeyboardButtonBottomConstraint = NSLayoutConstraint(item: self.nextKeyboardButton, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1.0, constant: -10.0)
  5. self.view.addConstraints([nextKeyboardButtonLeftSideConstraint, nextKeyboardButtonBottomConstraint])
  6. }
为了更好的梳理代码的结构,创建一个新的方法名为addKeyboardButtons,然后在 viewDidLoad 中调用它。虽然这里只有几个按钮,但是在真实项目中,将会有更多的按钮。在 addKeyboardButtons 中调用 addNextKeyboardButton。
 
  1. class KeyboardViewController: UIInputViewController {
  2. ...
  3. override func viewDidLoad() {
  4. super.viewDidLoad()
  5. addKeyboardButtons()
  6. }
  7. func addKeyboardButtons() {
  8. addNextKeyboardButton()
  9. }
  10. ...
  11. }
现在我们来添加点按钮,创建一个UIButton!类型的dotButton属性。
 
  1. class KeyboardViewController: UIInputViewController {
  2. var nextKeyboardButton: UIButton!
  3. var dotButton: UIButton!
  4. ...
  5. }
增加一个名为 addDot 的方法。使用系统按钮来初始化名为 dotButton 的属性。增加一个 TouchUpInside 事件回调函数。设置一个大字体然后增加圆角,同时增加约束来限制它距离水平中心50个points,垂直居中。这个代码应该和下面nextKeyboardButton部分类似。
 
  1. func addDot() {
  2. // initialize the button
  3. dotButton = UIButton.buttonWithType(.System) as UIButton
  4. dotButton.setTitle(".", forState: .Normal)
  5. dotButton.sizeToFit()
  6. dotButton.setTranslatesAutoresizingMaskIntoConstraints(false)
  7. // adding a callback
  8. dotButton.addTarget(self, action: "didTapDot", forControlEvents: .TouchUpInside)
  9. // make the font bigger
  10. dotButton.titleLabel.font = UIFont.systemFontOfSize(32)
  11. // add rounded corners
  12. dotButton.backgroundColor = UIColor(white: 0.9, alpha: 1)
  13. dotButton.layer.cornerRadius = 5
  14. view.addSubview(dotButton)
  15. // makes the vertical centers equa;
  16. var dotCenterYConstraint = NSLayoutConstraint(item: dotButton, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1.0, constant: 0)
  17. // set the button 50 points to the left (-) of the horizontal center
  18. var dotCenterXConstraint = NSLayoutConstraint(item: dotButton, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1.0, constant: -50)
  19. view.addConstraints([dotCenterXConstraint, dotCenterYConstraint])
  20. }
接下来对于dash,delete 和 hideKeyboard,这个过程都比较类似。这个deleteButton会从proxy使用deleteBackward方法,然后hideKeyboardButton会通过KeyboardViewController使用dismissKeyboard方法。
与dash相关的代码几乎和dotButton代码一致。为了将dashButton按钮在水平方向与 点 按钮对称,只要将水平约束中的常量改变一下符号即可。
 
  1. func addDash() {
  2. ...
  3. // set the button 50 points to the left (-) of the horizontal center
  4. var dotCenterXConstraint = NSLayoutConstraint(item: dotButton, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1.0, constant: -50)
  5. view.addConstraints([dashCenterXConstraint, dashCenterYConstraint])
回删
当被按下时,这个删除按钮会通过textDocumentProxy,使用deleteBackword删除字符。这个布局约束会和nextKeyboardButton对称(.Left -> .Right, .Bottom->.Top)
 
  1. func addDelete() {
  2. deleteButton = UIButton.buttonWithType(.System) as UIButton
  3. deleteButton.setTitle(" Delete ", forState: .Normal)
  4. deleteButton.sizeToFit()
  5. deleteButton.setTranslatesAutoresizingMaskIntoConstraints(false)
  6. deleteButton.addTarget(self, action: "didTapDelete", forControlEvents: .TouchUpInside)
  7. deleteButton.backgroundColor = UIColor(white: 0.9, alpha: 1)
  8. deleteButton.layer.cornerRadius = 5
  9. view.addSubview(deleteButton)
  10. var rightSideConstraint = NSLayoutConstraint(item: deleteButton, attribute: .Right, relatedBy: .Equal, toItem: view, attribute: .Right, multiplier: 1.0, constant: -10.0)
  11. var topConstraint = NSLayoutConstraint(item: deleteButton, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1.0, constant: +10.0)
  12. view.addConstraints([rightSideConstraint, topConstraint])
隐藏键盘
当被按下时,这个hideKeyboardButton会在KeyboardViewController上调用dismissKeyboard。
 
  1. func addHideKeyboardButton() {
  2. hideKeyboardButton = UIButton.buttonWithType(.System) as UIButton
  3. hideKeyboardButton.setTitle("Hide Keyboard", forState: .Normal)
  4. hideKeyboardButton.sizeToFit()
  5. hideKeyboardButton.setTranslatesAutoresizingMaskIntoConstraints(false)
  6. hideKeyboardButton.addTarget(self, action: "dismissKeyboard", forControlEvents: .TouchUpInside)
  7. view.addSubview(hideKeyboardButton)
  8. var rightSideConstraint = NSLayoutConstraint(item: hideKeyboardButton, attribute: .Right, relatedBy: .Equal, toItem: view, attribute: .Right, multiplier: 1.0, constant: -10.0)
  9. var bottomConstraint = NSLayoutConstraint(item: hideKeyboardButton, attribute: .Bottom, relatedBy: .Equal, toItem: view, attribute: .Bottom, multiplier: 1.0, constant: -10.0)
  10. view.addConstraints([rightSideConstraint, bottomConstraint])
  11. }
使用Nib文件
如果写约束并非你擅长的方式,你可以创建一个界面文件,然后将它添加到你的inputView。
创建一个界面文件
右击MorseCodeKeyboard文件组,然后选择创建新文件。
选择User Interface,然后View Template,命名为CustomKeyboardInterface。
选择File’s Owner,然后在Identity Inspector标签下,将类的名字改为KeyboardViewController。
在视图中加入一个按钮,然后将Title设置为We ? Swift。这个界面应该和这个有点相似:
加载界面
在 init(nibName, bundle) 构造函数内,加载这个 CustomKeyboard 文件,然后保存一个对于这个界面的引用。
 
  1. class KeyboardViewController: UIInputViewController {
  2. ...
  3. var customInterface: UIView!
  4. init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
  5. super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
  6. var nib = UINib(nibName: "CustomKeyBoardInterface", bundle: nil)
  7. let objects = nib.instantiateWithOwner(self, options: nil)
  8. customInterface = objects[0] as UIView
  9. }
  10. ...
  11. }
将它添加到 inputView
在 viewDidLoad 方法中,将这个自定义界面添加到 inputView。
 
  1. class KeyboardViewController: UIInputViewController {
  2. ...
  3. override func viewDidLoad() {
  4. super.viewDidLoad()
  5. view.addSubview(customInterface)
  6. ...
  7. }
  8. ...
  9. }
为按钮添加回调函数
 
  1. class KeyboardViewController: UIInputViewController {
  2. ...
  3. @IBAction func didTapWeheartSwift() {
  4. var proxy = textDocumentProxy as UITextDocumentProxy
  5. proxy.insertText("We ? Swift")
  6. }
  7. ...
  8. }
将按钮事件绑定到回调函数
在按钮上右击,然后单击并拖拽 touchUpInse 事件到 didTapWeHeartSwift IBAction。
最后,这个代码应该和这个差不多。
在你的设备上安装应用
在设备上运行你的项目。他会增加一个自定义键盘在你的设备上,但是在你使用它之前,你必须安装它。
进入设置>通用。选择键盘-应该在选项的底部。
选择键盘。
选择增加新键盘。然后你会看到MorseCode的键盘,选择然后安装这个键盘。
现在我们可以再次运行这个应用,然后使用你的键盘了。 

iOS输入法开发(Swift)相关推荐

  1. android输入法框架分析,Android与iOS输入法开发框架比较谈

    对于任何一个使用手机的人,有一样工具是不可能缺少的,它既不是微信之类的社交工具,也不是支付宝之类的金融工具(事实上这两个都越界了),而是输入法这样的输入工具.更重要的是,输入法还是一种特权工具,因为它 ...

  2. ios 输入法扩展_搜狗输入法 iOS 版开发与优化实践

    输入法是一种对性能要求极高的产品,不同于普通应用开发,很多在普通应用开发看来不是问题的,在输入法看来却是比较关键.同时,由于 iOS 系统的某些限制,输入法不得不在产品功能和性能方面做出调整,以尽可能 ...

  3. 专访搜狗输入法 iOS 版开发负责人李腾杰:第三方输入法开发与优化实践

    输入法是一种对性能要求极高的产品,不同于普通应用开发,很多在普通应用开发看来不是问题的,在输入法看来却是比较关键.同时,由于 iOS 系统的某些限制,输入法不得不在产品功能和性能方面做出调整,以尽可能 ...

  4. iOS开发Swift篇—(六)流程控制

    iOS开发Swift篇-(六)流程控制 一.swift中的流程控制 Swift支持的流程结构如下: 循环结构:for.for-in.while.do-while 选择结构:if.switch 注意:这 ...

  5. 李洪强iOS开发Swift篇—02_变量和常量

    李洪强iOS开发Swift篇-02_变量和常量 一.语言的性能 (1)根据WWDC的展示 在进行复杂对象排序时Objective-C的性能是Python的2.8倍,Swift的性能是Python的3. ...

  6. pythonios脚本语言-iOS开发Swift篇—(一)简单介绍

    一.简介 Swift是苹果于2014年WWDC(苹果开发者大会)发布的全新编程语言 Swift在天朝译为"雨燕",是它的LOGO 是一只燕子,跟Objective-C一样,可以用于 ...

  7. iOS 跨平台开发,该用 Flutter 还是 Swift?

    [CSDN 编者按]在商业和开源代码中被广泛使用的 Flutter 和 Swift 你更中意哪一个呢?本文对两者的优势.性能.流行度等方面进行比较分析,帮助您找出更适合自己项目的框架或语言. 作者 | ...

  8. iOS开发 swift 3dTouch实现 附代码

    iOS开发 swift 3dTouch实现 附代码 一.What? 从iphone6s开始,苹果手机加入了3d touch技术,最简单的理解就是可以读取用户的点击屏幕力度大小,根据力度大小给予不同的反 ...

  9. 了解Swift:15个适合iOS应用开发的初学者友好资源

    现在是开始在iOS上使用Swift编程语言进行编程的好时机. 但是从哪里开始呢? 尽管有很多很棒的Swift和iOS程序员免费资源,但是并不是所有的资源都是为初学者设计的. 从Apple自己出色的指南 ...

最新文章

  1. 其实win10要比win7的安全性强很多
  2. 基于 RocketMQ Prometheus Exporter 打造定制化 DevOps 平台
  3. 组合数据类型练习,英文词频统计实例9-21
  4. 剪裁tiff影像数据_能看更会用,超擎影像云平台带你轻松玩转海量影像!
  5. 总结获取原生JS(javascript)的父节点、子节点、兄弟节点
  6. C++ primer 第7章 类
  7. java arraylist底层实现原理_ArrayList和LinkedList底层原理
  8. vs怎么更改编译的堆空间_再见吧 buildSrc, 拥抱 Composing builds 提升 Android 编译速度...
  9. 090525 T 站点地图接口
  10. 从决策树学习谈到贝叶斯分类算法、EM、HMM - 结构之法 算法之道
  11. 加速你的vs.net开发环境
  12. 大数据超详细面试题汇总(附答案)
  13. Qt练习项目--鼠标连点器
  14. 算法——最短路径应用
  15. Centos7 ,使用grep,cut 、awk 提取IP地址
  16. 国内外无代码可视化开发平台一览
  17. Guitar Pro8苹果mac最新版本下载安装教程
  18. python 线性回归显著性检验_回归方程及回归系数的显著性检验_stata显著性检验...
  19. 小度电视伴侣与小米电视音响对比评测
  20. 10Mbps是多少网速呢

热门文章

  1. hdu1429 胜利大逃亡(续) (BFS+简单状态压缩)
  2. 什么是GIT,以及git的常见命令
  3. 火狐stylish插件解决BIOS之家没有滚动条问题
  4. php发邮件有时很卡,phpmailer发邮件常见的问题及解决方法汇总
  5. Thinkpad E14装ubuntu 16.04双系统问题
  6. OpenShift Authentication
  7. js分組, 实际应用
  8. 写计算机老师的一封信200,写给老师的一封信200字
  9. Java中Callable和Future
  10. Jenkins自动化部署环境搭建