iOS 输入限制之 InputKit

作者: tingxins | 来源:发表于2017-06-29 22:27 被阅读1865次
InputKit-logo2-dynamic.gif

前言

最近接手了两个 O2O 的老项目,其中的 Bug 也不言而喻,单看项目中的布局就有 n 种不同的方式,有用纯代码的,有用 Masonry 的,有用 VFL 的,也有用 Xib 的,更有用代码约束等等等,🐮。不扯远了,回归正题。

由于这两个项目是 O2O 项目,因此针对输入组件的限制相比其他类型的项目要多一些,比如商品价格输入(如:保留3位整数,2位小数等)、买家留言字数限制、不能输入中文、不能输入英文、只能输入数字等等限制。

于是输入限制 InputKit 诞生了!本文主要简单介绍 InputKit 的使用及相关注意事项。(微博地址

InputKit

InputKit 是一个轻量级的,专门用于做输入限制的第三方库,灵感源自 BlocksKit,在项目中,主要为了解决三个问题:

  • 解耦
  • 需求
  • Bug

解耦

所谓解耦,即在开发项目中工程师不需要仅仅只为做个输入限制,就在项目中到处写 UITextFieldDelegate 协议中的方法,如:


- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    // Coding
}

只需继承 InputKit 中的类即可,然后设置相关的限制属性即可,无需设置 delegate。以 TXLimitedTextFieldTypePrice 类型为例,如:

Objective-C


// 创建 TXLimitedTextField 实例
TXLimitedTextField *textField = [[TXLimitedTextField alloc] initWithFrame:CGRectMake(20, 200, 100, 30)];
// 如 limitedType 不设置,默认 TXLimitedTextFieldTypeDefault
textField.limitedType = TXLimitedTextFieldTypePrice;
// 限制 10 的输入长度
textField.limitedNumber = 10;
// 保留 5 位整数位
textField.limitedPrefix = 5;
// 保留 2 位小数位
textField.limitedSuffix = 2;
[self.view addSubview:textField];

Swift


let textField = LimitedTextField(frame: CGRect(x: 20, y: 200, width: 100, height: 30))
textField.limitedType = .price
textField.limitedNumber = 10
textField.limitedPrefix = 5
textField.limitedSuffix = 2
view.addSubview(textField)

如果想设置 textField 的 delegate 也可以(即 textField.delegate = self),不会影响其限制功能,就像使用普通的 UITextField 一样,毫无差异,非常方便。

Demo 截图:

inputKit-demo-price.gif

需求

文章开头提到过,需求即针对商品价格输入(如:保留3位整数,2位小数等)、买家留言字数限制、不能输入中文、不能输入英文、只能输入数字等等做限制。

如果针对上述的部分需求做定制键盘,是完全没必要的,因为工作量增多且并不能从源头解决问题,比如:用户使用粘贴功能、使用键盘提示文本等等,导致定制的键盘也是白搭。因此 InputKit 从源头解决该问题,针对用户的输入进行筛选并限制。比如我们只能让用户输入中文:

Objective-C


TXLimitedTextField *textField = [[TXLimitedTextField alloc] initWithFrame:CGRectMake(20, 200, 100, 30)];

// 自定义输入限制类型
textField.limitedType = TXLimitedTextFieldTypeCustom;

// 限制最大输入长度
textField.limitedNumber = 10;

// limitedRegExs 是一个数组类型的参数,数组元素类型即正则表达式,如:kTXLimitedTextFieldChineseOnlyRegex 是一个常量,其值为:“^[\u4e00-\u9fa5]{0,}$”,即代表匹配中文的正则
textField.limitedRegExs = @[kTXLimitedTextFieldChineseOnlyRegex];

[self.view addSubview:textField];

Swift 代码略

关于上述的正则表达式,在 InputKit 中的 TXMatchConst.h 头文件中提供了一些常用的,比如:只能输入数字、中文、字母等等,欢迎大家在 GitHub 上 PR。(注意:此处的正则表达式限制的是输入源头,而非结果!不然会导致用户无法输入。体会一下哈)。

Demo 截图:

inputKit-demo-custom.gif

Bug

在没使用 InputKit 之前,有时候,运行到程序的某处,点击输入框,程序莫名其妙的卡死,过会儿就闪退了。相信不少人遇到过,后来发现是 self.delegate = self(self 即输入框对象) 导致的。注释后,发现没问题,打开后,程序又闪退,后来发现原来是 self.delegate = self 引起的死循环,因此不得不注释该句代码。

上述的这些问题,如:在项目中 UITextFieldDelegate 协议方法遍地都是,以及一不小心使用了 self.delegate = self 时,还会出现死循环等等,InputKit 都解决了。

使用 InputKit 后,self.delegate = self 程序不再卡死。(晚点会再发一篇软文针对 self.delegate = self 的问题进行剖析)。

至此,需求、Bug 均已解决。👀

开源

GitHub 项目及 Demo 地址:https://github.com/tingxins/InputKit

有什么问题或者更好的建议,直接提 issue 或者 PR。

相关文章

网友评论

  • b6da66a175ae:请问 使用xib创建textField 设置了textField.limitedType = TXLimitedTextViewTypePrice 用户可以输入 但是输入框无法获取值,长度限制依旧有效 用代码创建也可以限制 就是xib不行
  • 黄二瓜:https://github.com/tingxins/InputKit/issues/9 请看下这个issue, 在swfit3 的版本中,如果不设置 LimitedTextField 的 delegate 的话无法进行输入限制,可以在 Swift Demo 中 fileprivate func getLimitedTextField(yScale: Float) ->LimitedTextField ()方法 注释掉 textField.delegate = self 进行验证
    黄二瓜:@范范饭特稀 提了一个PR https://github.com/tingxins/InputKit/pull/11
    范范饭特稀:我也发现了,而且限制中文时,若使用苹果键盘,还得加这个TextField.isTextSelecting = true
  • Ronda:您好,使用该库需要继承,在使用textView时,需要设置占位符,但是该库提供的textView没有设置占位符的属性。一般出现textField和textView的地方都需要设置占位符吧。我觉得可以加上
    tingxins:@Ronda InputKit issue#6: https://github.com/tingxins/InputKit/issues/6
  • 黄二瓜:已经不支持swift3 了么?
    黄二瓜:@tingxins 【 regEx.count > 0 】 swift3 中没有直接提供对字符串直接计算字符数的方法。 swift 4 提供了,不知道 string.count 是你写的扩展还是直接在 swift 4环境下写的 :dizzy_face:
    黄二瓜:@tingxins 通过pod 拉下来报错,通过下载的 demo 打开的话 报 `“Swift Language Version” (SWIFT_VERSION) is required to be configured correctly for targets which use Swift. Use the [Edit > Convert > To Current Swift Syntax…] menu to choose a Swift version or use the Build Settings editor to configure the build setting directly.` :cry:
    tingxins:@黄二峰 支持的呀
  • 黑幕居士:这个库真是太好用,解决了燃眉之急,之前做输入限制差点被中文联想搞晕,正好学习下处理光标选中的文字,已星(๑•̀ㅂ•́)و✧
  • Potato121:您好! 感谢您的分享。您文章末尾留下的链接把“。”也包含在链接里面,如果直接点击打开会找不到页面
    tingxins:谢谢提醒,已更新:smile:
  • 老初:您好,请问限制只能输入字母和数字可以这样写吗?
    limitedTextField.limitedRegExs = [kTXLimitedTextFieldNumberOnlyRegex, kTXLimitedTextFieldEnglishOnlyRegex]

    谢谢
    老初:@tingxins 好的,感谢:blush:
    tingxins:@老初 limitedRegExs 中的正则是按“与”匹配的,因此不可以,你可以在 TXMatchConst.h 文件中新增正则const,如果是字母数字-->^[A-Za-z0-9]+$。后期版本将继续完善这块功能。欢迎 GitHub PR

本文标题:iOS 输入限制之 InputKit

本文链接:https://www.haomeiwen.com/subject/jqwvcxtx.html