前言
最近接手了兩個 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 截圖:
需求
文章開頭提到過,需求即針對商品價格輸入(如:保留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 截圖:
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。