iOS郵箱模糊匹配功能集成

大家有些人應(yīng)該遇到產(chǎn)品汪提過(guò)這樣的需求,產(chǎn)品汪說(shuō):“某某App的訂單填寫(xiě)頁(yè),輸入用戶郵箱有個(gè)提示郵箱后綴的功能,很好用??!還可以根據(jù)各個(gè)郵箱類型用戶量來(lái)做一個(gè)優(yōu)先級(jí)的匹配哦。你可以不可以幫我實(shí)現(xiàn)哎!”這個(gè)做起來(lái)確實(shí)很煩的,產(chǎn)品汪是男的還可以拒絕掉,人家有啥功能你就做啥功能???但是如果是個(gè)漂亮的女產(chǎn)品汪,嬌滴滴的來(lái)和你說(shuō)~這個(gè)時(shí)候你能扛得住么?一不小心掉坑里了,答應(yīng)了,一時(shí)爽快了。但是碼代碼就很蛋疼了,別怕,有我在,已經(jīng)用一個(gè)自定義的textField全部集成好了~先看效果圖。


郵箱匹配效果圖.gif

一.介紹一下功能

當(dāng)輸入一個(gè)郵箱的數(shù)字,會(huì)默認(rèn)在后面匹配出來(lái)@qq.com,當(dāng)然這個(gè)默認(rèn)@qq.com可以換成其他的如@163.com等等。這里默認(rèn)是@qq.com,因?yàn)槲覀兊漠a(chǎn)品汪做過(guò)統(tǒng)計(jì)大多數(shù)用戶還是用的qq郵箱,所以默認(rèn)是@qq.com。
當(dāng)輸入@符號(hào)還是不會(huì)有所變化,但是如果在@之后再輸入字符,會(huì)將這個(gè)字符和你想要提示的郵箱后綴做匹配,我這里是需要匹配@qq.com,@163.com,@126.com,@yahoo.com,@139.com,@henu.com類型。例如:在@之后你輸入了1,這個(gè)時(shí)候會(huì)在@1之后匹配出來(lái)63.com。接著,當(dāng)你在@1之后又輸入了2,會(huì)在@12后面匹配出來(lái)6.com。這些匹配的優(yōu)先級(jí)是根據(jù)你給的需要匹配郵箱類型的順序來(lái)的,并且這些想要匹配的郵箱類型也是完全可配的,可根據(jù)產(chǎn)品汪的需求作自己的定制。

二.說(shuō)一下用法

1.先說(shuō)一下如果你是在xib中想實(shí)現(xiàn)這個(gè)功能,首先要拖拽一個(gè)textField,設(shè)置好約束,然后讓這個(gè)textField的類關(guān)聯(lián)到XLTextField,當(dāng)前前提你要下載并導(dǎo)入了XLTextField.h和XLTextField.m,切記不要忘了將textField.delegate設(shè)置給viewController,textField樣式可在xib自行設(shè)置,匹配的郵箱區(qū)域顏色可自行設(shè)置,然后在代碼中只需要調(diào)API

/**
*
*1.通過(guò)xib創(chuàng)建只需要賦值此參數(shù)即可
*@param mailTypeArray郵箱匹配類型
*
*/
@property(nonatomic,strong)NSMutableArray*mailTypeArray;

示例代碼:

self.textField.mailTypeArray= [NSMutableArrayarrayWithObjects:@"@qq.com",@"@163.com",@"@126.com",@"@yahoo.com",@"@139.com",@"@henu.com",nil];
self.textField.didPressedReturnCompletion = ^(UITextField * textField){
      //點(diǎn)擊return的回調(diào),是可選的 根據(jù)自己需求使用
};

XLTextField.h還提供了一個(gè)可選的mailMatchColor屬性這個(gè)屬性是UIColor類型的,是匹配郵箱類型的顏色,可根據(jù)需求自行設(shè)置。

/**
*Optional匹配的郵箱類型后綴默認(rèn)是RGB為170 170 170的顏色,可自行設(shè)置
*/
@property(nonatomic,strong)UIColor* mailMatchColor;

2.通過(guò)手動(dòng)frame創(chuàng)建兩個(gè)基本參數(shù)設(shè)置大小和字號(hào),其他設(shè)置可額外自行設(shè)置,調(diào)用API

/**
*2.通過(guò)手寫(xiě)創(chuàng)建textField時(shí)候調(diào)用
*
*@param frameframe大小
*@param fontSize textField大小
*
*@return self
*/
- (instancetype)initWithFrame:(CGRect)frame fontSize:(CGFloat)fontSize;

示例代碼:

XLTextField * field = [[XLTextField alloc] initWithFrame:CGRectMake(100, 200, 200, 30) fontSize:12];
field.placeholder = @"輸入郵箱地址";
field.mailTypeArray = [NSMutableArray arrayWithObjects:@"@qq.com",@"@163.com",@"@126.com",@"@yahoo.com",@"@139.com",@"@henu.com", nil];
Field.didPressedReturnCompletion = ^(UITextField * textField){
      //點(diǎn)擊return的回調(diào),是可選的 根據(jù)自己需求使用
};
field.mailMatchColor = [UIColor redColor]; 可選屬性
[self.view addSubview:field];

我在示例程序中只針對(duì)xib的textField寫(xiě)了手勢(shì)關(guān)閉,結(jié)束textField的輸入操作,手洞創(chuàng)建textField沒(méi)有寫(xiě)結(jié)束第一響應(yīng)者的操作。如果你在實(shí)際使用中,可以根據(jù)你的需求例如點(diǎn)擊鍵盤(pán)的完成按鈕,或者觸摸屏幕的View等場(chǎng)景下結(jié)束textField的鍵盤(pán)第一響應(yīng)者,從而取textField的text進(jìn)行額外的需求操作。
可根據(jù)自己需求定制自己的frame,font大小。不過(guò)不支持init和new初始化方法,即使用了也沒(méi)關(guān)系,會(huì)有一個(gè)溫馨的報(bào)錯(cuò)提示

- (instancetype)init__attribute__((unavailable("init方法不可用,請(qǐng)用initWithName:fontSzie:")));
+ (instancetype)new__attribute__((unavailable("init方法不可用,請(qǐng)用initWithName:fontSzie:")));

更新版本內(nèi)容:

如果接入的類需要在textField的代理方法中做操作 可實(shí)現(xiàn)對(duì)應(yīng)的協(xié)議即可
@protocol XLEmailTextFieldDelegate <NSObject>

@optional
- (BOOL)XLTextFieldShouldBeginEditing:(UITextField *)textField;
- (void)XLTextFieldDidBeginEditing:(UITextField *)textField;
- (void)XLTextFieldDidEndEditing:(UITextField *)textField;
- (BOOL)XLTextField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
- (BOOL)XLTextFieldShouldReturn:(UITextField *)textField;

@end

三.介紹一下實(shí)現(xiàn)原理

1.可能你不看源碼,就認(rèn)為是一個(gè)textField實(shí)現(xiàn)了全部功能,其實(shí)No.我這里是配合了一個(gè)Label,在xib實(shí)現(xiàn)時(shí)利用aulayout手動(dòng)添加Label。textField只是用來(lái)讓用戶輸入,Label用來(lái)存儲(chǔ)匹配之后的郵箱(郵箱號(hào)碼+郵箱類型),并且展示。你看到的其實(shí)是Label的text內(nèi)容。當(dāng)最后結(jié)束編輯的時(shí)候,Label會(huì)將內(nèi)容復(fù)制給textField的text,然后清空Label。Label只是在這里提一下實(shí)現(xiàn)方式,真正使用的值還是通過(guò)textField.text拿到的值。在這里你可能會(huì)吐槽,為什么不用一個(gè)textField呢,多簡(jiǎn)單省事。但是事實(shí)是我嘗試過(guò)一個(gè)textField,中間遇到了一個(gè)坑,好像是textField一個(gè)bug,暫且這樣說(shuō) 因?yàn)楫?dāng)時(shí)確實(shí)是很奇葩的問(wèn)題,具體是那么也忘記了,這里也不展開(kāi)說(shuō)了,有興趣你可以用一個(gè)textField來(lái)嘗試一下哈。

2.textField的代理方法全部封裝在textField.m內(nèi)部,在內(nèi)部已經(jīng)處理了這些代理,更加方便他人調(diào)用,不用再花很多心思在調(diào)試textField的代理方法上。不論是用xib還是用手動(dòng)代碼創(chuàng)建,都不需要設(shè)置textField.delegate給控制器。

3.在textField的shouldChangeCharactersInRange代理方法中針對(duì)你輸入的每一個(gè)字符進(jìn)行郵箱的匹配,下面會(huì)有這一塊的完整代碼。在textFieldDidEndEditing代理方法中將Label的值賦值給textField.text,然后將Label.text清空,直接取textField.text作為我們最終的結(jié)果。

下面貼上匹配郵箱過(guò)程的關(guān)鍵代碼,并且每行都有注釋,如果想要看更多源碼歡迎在點(diǎn)擊下載源碼,查看所有源碼。

/**
*匹配郵箱過(guò)程
*
*@param rangerange
*@param string用戶輸入string
*/

- (void)configMailMatchingRange:(NSRange)range replacementString:(NSString*)string
{
//獲取完整的輸入文本
NSString*completeStr = [self.textstringByReplacingCharactersInRange:rangewithString:string];

//以@符號(hào)分割文本
NSArray*temailArray = [completeStrcomponentsSeparatedByString:@"@"];

//獲取郵箱前綴
NSString*emailString = [temailArrayfirstObject];

//郵箱匹配沒(méi)有輸入@符號(hào)時(shí)用@匹配
NSString*matchString =@"@";
if(temailArray.count>1){
//如果已經(jīng)輸入@符號(hào)截取@符號(hào)以后的字符串作為匹配字符串
matchString = [completeStrsubstringFromIndex:emailString.length];
}

//匹配郵箱得到所有跟當(dāng)前輸入匹配的郵箱后綴
NSMutableArray*suffixArray = [selfcheckEmailStr:matchString];

//邊界控制如果沒(méi)有跟當(dāng)前輸入匹配的后綴置為@""
NSString*fixStr = suffixArray.count>0? [suffixArrayfirstObject] :@"";

//將lblEmail部分字段隱藏
NSIntegercutLenth = suffixArray.count>0? completeStr.length: emailString.length;

//最終的郵箱地址
self.email= fixStr.length>0? [NSStringstringWithFormat:@"%@%@",emailString,fixStr] : completeStr;

//設(shè)置lblEmail的attribute
NSMutableAttributedString*attributeString = [[NSMutableAttributedStringalloc]initWithString:[NSStringstringWithFormat:@"%@%@",emailString,fixStr]];

[attributeStringaddAttribute:NSForegroundColorAttributeNamevalue:[UIColorclearColor]range:NSMakeRange(0,cutLenth)];

self.mailLabel.attributedText= attributeString;

//清空文本框內(nèi)容時(shí)隱藏lblEmail
if(completeStr.length==0){
self.mailLabel.text=@"";
self.email=@"";
}
}

更新了文件,因?yàn)榻裉煳以趯?shí)際項(xiàng)目中又用到了郵箱匹配,不過(guò)因?yàn)槭抢享?xiàng)目,原來(lái)的基礎(chǔ)上已經(jīng)實(shí)現(xiàn)了textField的代理方法,并且有一些額外的操作,這個(gè)時(shí)候因?yàn)榇藅extField代理是自己,所以代理方法是私有的,為了不影響之前的老代碼,特意對(duì)外開(kāi)放了textField的代理方法,也算是適配器模式的一種場(chǎng)景,改變接口即可復(fù)用老代碼??筛鶕?jù)
自身需要去實(shí)現(xiàn)customDelegate。
如果你還喜歡,請(qǐng)留下一個(gè)Star,在這里先說(shuō)聲謝謝啦??~
本人水平有限,如有紕漏指出歡迎指正!
如果您在使用中 有不能滿足的需求~可以提出來(lái) 我做修改 盡量滿足大家的需求。
在這里要感謝下@QYunFat,給的好的建議在點(diǎn)擊return賦值textField,當(dāng)時(shí)沒(méi)考慮到這個(gè),已添加??
iOS 開(kāi)發(fā)技術(shù)交流群號(hào):529560119 ,提供各種最新權(quán)威學(xué)習(xí)書(shū)籍及開(kāi)發(fā)視頻

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,695評(píng)論 19 139
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,658評(píng)論 4 61
  • 他回來(lái)了,離家一個(gè)多月 再次回來(lái) 她看著他 有些許的陌生。 結(jié)婚幾個(gè)月 她和他真正在一起的時(shí)間不超過(guò)一個(gè)月,他在八...
    君之語(yǔ)閱讀 355評(píng)論 0 1
  • 別以為別人都在乎你 其實(shí)最在乎你的就是你自己 別總以為別人都在乎你 其實(shí)別人也都是只在乎自己 所以有時(shí)不必刻意偽裝自己
    末時(shí)刻閱讀 959評(píng)論 0 0
  • C語(yǔ)言中提供了三種邏輯運(yùn)算符: &&(與運(yùn)算)||(或運(yùn)算)!(非運(yùn)算) 邏輯運(yùn)算的值 邏輯運(yùn)算的值也為“真”和“...
    diveinljq閱讀 846評(píng)論 0 0

友情鏈接更多精彩內(nèi)容