前言
大部分App 在輸入表單的時(shí)候都是采用,用戶(hù)輸入滿足條件后,功能按鈕才能點(diǎn)擊。
我個(gè)人覺(jué)得這是很沒(méi)體驗(yàn)的,為什么呢?
拿登錄舉例,產(chǎn)品需求是登錄名稱(chēng)必須滿足在幾個(gè)文字以?xún)?nèi),密碼必須下劃線、數(shù)字、英文組合。如果輸入不滿足要求,按鈕就不能點(diǎn)擊。提示信息是放到占位文字里的,只要輸入了文字,就看不見(jiàn)提示了。而此時(shí)用戶(hù)可能會(huì)迷糊,不知道該怎么做,一臉懵逼的感覺(jué)。
而另一種思路是,讓按鈕一直可以點(diǎn)擊。只要用戶(hù)點(diǎn)擊按鈕,就提示相關(guān)的信息,例如哪一行不滿足要求,給個(gè)紅色背景框什么的。這樣用戶(hù)就知道問(wèn)題所在了。
我覺(jué)得好的體驗(yàn)就是讓用戶(hù)得到各種信息反饋,而不是說(shuō)輸入內(nèi)容不能包含emoji,就阻斷用戶(hù)的輸入,讓用戶(hù)的輸入沒(méi)反應(yīng),然后一臉懵逼。因此巴拉巴拉。。。好了,實(shí)在編不下去了!?。?/p>

Talk is cheap. Show me the code.
AGVerifyManager
思路描述
- 參考了 Masonry 的鏈?zhǔn)秸Z(yǔ)法,鏈?zhǔn)秸Z(yǔ)法的優(yōu)雅非常適合用來(lái)連續(xù)驗(yàn)證多個(gè)數(shù)據(jù)。
- 因?yàn)橛脩?hù)需要驗(yàn)證的數(shù)據(jù)是變化且各不相同的,所以把變化隔離開(kāi)來(lái),獨(dú)立封裝。
- 驗(yàn)證的時(shí)候需要集中處理,所以用代碼塊統(tǒng)一了起來(lái)。
cocoapods 集成
platform :ios, '7.0'
target 'AGVerifyManagerDemo' do
pod 'AGVerifyManager'
end
使用說(shuō)明
- 創(chuàng)建遵守并實(shí)現(xiàn)<AGVerifyManagerVerifiable>協(xié)議的驗(yàn)證器類(lèi);
- 如:Emoji表情驗(yàn)證器、手機(jī)號(hào)碼驗(yàn)證器 ...
- 使用 AGVerifyManager 搭配相應(yīng)的驗(yàn)證器對(duì)數(shù)據(jù)進(jìn)行驗(yàn)證和結(jié)果回調(diào)。
-
- AGVerifyManager 可以直接執(zhí)行驗(yàn)證,然后釋放Block;
- 也可以保存Block,通過(guò)Key個(gè)別進(jìn)行驗(yàn)證,重復(fù)進(jìn)行驗(yàn)證,或者在后臺(tái)線程進(jìn)行驗(yàn)證。
-
- 具體可參考 Demo
- 下面是代碼片段
// 1. 判斷用戶(hù)輸入文字限制
ATTextLimitVerifier *usernameVerifier = [ATTextLimitVerifier new];
usernameVerifier.minLimit = 2;
usernameVerifier.maxLimit = 7;
usernameVerifier.maxLimitMsg =
[NSString stringWithFormat:@"文字不能超過(guò)%@個(gè)字符!", @(usernameVerifier.maxLimit)];
// 2. 判斷文字是否包含 emoji ??
ATEmojiVerifier *emojiVerifier = [ATEmojiVerifier new];
emojiVerifier.errorMsg = @"請(qǐng)輸入非表情字符!";
// 3. 判斷文字是否包含空格
ATWhiteSpaceVerifier *whiteSpaceVerifier = [ATWhiteSpaceVerifier new];
// 4. 準(zhǔn)備驗(yàn)證
__weak typeof(self) weakSelf = self;
[self.verifyManager ag_addVerifyForKey:@"Key" verifying:^(id<AGVerifyManagerVerifying> start) {
__strong typeof(weakSelf) self = weakSelf;
start
// 用法一:傳入驗(yàn)證器和需要驗(yàn)證的數(shù)據(jù);
.verifyData(usernameVerifier, self.nameTextField.text)
.verifyData(emojiVerifier, self.nameTextField.text)
// 用法二:傳入驗(yàn)證器、數(shù)據(jù)、提示的內(nèi)容;
.verifyDataWithMsg(whiteSpaceVerifier, self.nameTextField.text, @"文字不能包含空格!")
// 用法三:傳入驗(yàn)證器、數(shù)據(jù)、你想傳遞的對(duì)象;文本框閃爍
.verifyDataWithContext(self, self.nameTextField.text, self.nameTextField);
} completion:^(AGVerifyError *firstError, NSArray<AGVerifyError *> *errors) {
__strong typeof(weakSelf) self = weakSelf;
if ( firstError ) {
// 驗(yàn)證不通過(guò)
self.resultLabel.textColor = [UIColor redColor];
self.resultLabel.text = firstError.msg;
// 文本框閃爍
[errors enumerateObjectsUsingBlock:^(AGVerifyError *obj, NSUInteger idx, BOOL *stop) {
// 取出傳遞的對(duì)象,根據(jù)自身業(yè)務(wù)處理。
if ( obj.context == self.nameTextField ) {
// 取色
UIColor *color;
if ( obj.code == 100 ) {
color = [UIColor redColor];
}
else if ( obj.code == 200 ) {
color = [UIColor purpleColor];
}
// 動(dòng)畫(huà)
[UIView animateWithDuration:0.15 animations:^{
self.nameTextField.backgroundColor = color;
} completion:^(BOOL finished) {
self.nameTextField.backgroundColor = [UIColor whiteColor];
}];
}
}];
}
else {
// TODO
self.resultLabel.textColor = [UIColor greenColor];
self.resultLabel.text = @"驗(yàn)證通過(guò)!";
self.nameTextField.backgroundColor = [UIColor whiteColor];
}
}];
// 5. 執(zhí)行驗(yàn)證
[self.verifyManager ag_executeVerifyBlockForKey:@"Key"];
多數(shù)情況下
在項(xiàng)目中,使用最多的還是用來(lái)過(guò)濾網(wǎng)絡(luò)請(qǐng)求的數(shù)據(jù)。
例如 API參數(shù)驗(yàn)證,API返回狀態(tài)碼驗(yàn)證。如果出錯(cuò),APIManager 就會(huì)調(diào)用請(qǐng)求失敗的回調(diào),而我們就在失敗回調(diào)里彈框提示錯(cuò)誤信息。例如 token 過(guò)期、密碼錯(cuò)誤、沒(méi)有權(quán)限等信息。AGVerifyManager 是采用協(xié)議的方式驗(yàn)證的,所以驗(yàn)證器是誰(shuí)遵守了協(xié)議都可以做的。例如 TableViewCell 遵守了協(xié)議,就可以自己做裁判還當(dāng)運(yùn)動(dòng)員。