IOS 圖形驗(yàn)證碼

先給大家擺上效果圖。

1.自定義MQVerCodeInputView類 繼承 UIView

MQVerCodeInputView.h 文件中:

#import <UIKit/UIKit.h>

typedefvoid(^MQTextViewBlock)(NSString*text);

@interfaceMQVerCodeInputView :UIView

@property(nonatomic,assign)UIKeyboardTypekeyBoardType;

@property(nonatomic,copy)MQTextViewBlockblock;

/*驗(yàn)證碼的最大長度*/

@property(nonatomic,assign)NSIntegermaxLenght;

/*未選中下的view的borderColor*/

@property(nonatomic,strong)UIColor*viewColor;

/*選中下的view的borderColor*/

@property(nonatomic,strong)UIColor*viewColorHL;

-(void)mq_verCodeViewWithMaxLenght;

@end

2.UIView+MQ創(chuàng)建類目文件

UIView+MQ.h文件:

#import <UIKit/UIKit.h>

@interfaceUIView (MQ)

@property(nonatomic)IBInspectableCGFloatcornerRadius;

/**頭像圓角*/

@property(nonatomic)IBInspectableBOOLavatarCorner;

/**邊框*/

@property(nonatomic)IBInspectableCGFloatborderWidth;

/**邊框顏色*/

@property(nonatomic,strong)IBInspectableUIColor*borderColor;

+ (__kindofUIView*)MQLoadNibView;

- (void)MQSetViewCircleWithBorderWidth:(CGFloat) width andColor:(UIColor*)borColor;

- (void)MQViewSetCornerRadius:(CGFloat)radius;

@end


UIView+MQ.m文件:

#import"UIView+MQ.h"

#import <objc/runtime.h>

@implementationUIView (MQ)

- (CGFloat)cornerRadius

{

return[objc_getAssociatedObject(self,@selector(cornerRadius))floatValue];

}

- (void)setCornerRadius:(CGFloat)cornerRadius

{

self.layer.cornerRadius= cornerRadius;

self.layer.masksToBounds= (cornerRadius >0);

}

- (BOOL)avatarCorner{

return[objc_getAssociatedObject(self,@selector(cornerRadius))floatValue] >0;

}

- (void)setAvatarCorner:(BOOL)corner{

if(corner){

self.layer.cornerRadius=CGRectGetWidth(self.frame)/2;

self.layer.masksToBounds= corner;

}

}

- (CGFloat)borderWidth{

return[objc_getAssociatedObject(self,@selector(borderWidth))floatValue];

}

- (void)setBorderWidth:(CGFloat)borderWidth{

self.layer.borderWidth= borderWidth;

self.layer.masksToBounds= (borderWidth >0);

}

- (UIColor*)borderColor{

returnobjc_getAssociatedObject(self,@selector(borderColor));

}

- (void)setBorderColor:(UIColor*)borderColor{

self.layer.borderColor= borderColor.CGColor;

}

+ (__kindofUIView*)MQLoadNibView{

NSString*className =NSStringFromClass([selfclass]);

return[[[UINibnibWithNibName:classNamebundle:nil]instantiateWithOwner:selfoptions:nil]lastObject];

}

-(void)MQViewSetCornerRadius:(CGFloat)radius{

[self.layersetMasksToBounds:YES];

[self.layersetCornerRadius:radius];

}

-(void)MQSetViewCircleWithBorderWidth:(CGFloat) width andColor:(UIColor*)borColor{

[selfMQViewSetCornerRadius:(self.frame.size.height/2)];

self.layer.borderWidth=width;

self.layer.borderColor=[borColorCGColor];

}

@end



3.MQVerCodeInputView.m 文件中:

#import"MQVerCodeInputView.h"

#import"Masonry.h"

#import"UIView+MQ.h"

@interfaceMQVerCodeInputView()

@property(nonatomic,strong)UIView*contairView;

@property(nonatomic,strong)UITextView*textView;

@property(nonatomic,strong)NSMutableArray*viewArr;

@property(nonatomic,strong)NSMutableArray*labelArr;

@property(nonatomic,strong)NSMutableArray*pointlineArr;

@end

@implementationMQVerCodeInputView

-(instancetype)initWithFrame:(CGRect)frame{

self= [superinitWithFrame:frame];

if(self) {

[selfinitDefaultValue];

}

returnself;

}

-(void)initDefaultValue{

//初始化默認(rèn)值

self.maxLenght=4;

_viewColor= [UIColorcolorWithRed:228/255.0green:228/255.0blue:228/255.0alpha:1];

_viewColorHL= [UIColorcolorWithRed:255/255.0green:70/255.0blue:62/255.0alpha:1];

self.backgroundColor= [UIColorclearColor];

[selfbeginEdit];

}

-(void)mq_verCodeViewWithMaxLenght{

//創(chuàng)建輸入驗(yàn)證碼view

if(_maxLenght<=0) {

return;

}

if(_contairView) {

[_contairViewremoveFromSuperview];

}

_contairView= [UIViewnew];

_contairView.backgroundColor= [UIColorclearColor];

[selfaddSubview:_contairView];

[_contairViewmas_makeConstraints:^(MASConstraintMaker*make) {

make.height.equalTo(self.mas_height);

make.centerX.equalTo(self);

make.centerY.equalTo(self);

}];

[_contairViewaddSubview:self.textView];

[self.textViewmas_makeConstraints:^(MASConstraintMaker*make) {

make.edges.equalTo(_contairView);

}];

CGFloatpadding = (CGRectGetWidth(self.frame) -_maxLenght*CGRectGetHeight(self.frame))/(_maxLenght-1);

UIView*lastView;

for(inti=0; i

UIView*subView = [UIViewnew];

subView.backgroundColor= [UIColorwhiteColor];

subView.cornerRadius=4;

subView.borderWidth= (0.5);

subView.userInteractionEnabled=NO;

[_contairViewaddSubview:subView];

[subViewmas_makeConstraints:^(MASConstraintMaker*make) {

if(lastView) {

make.left.equalTo(lastView.mas_right).with.offset(padding);

}else{

make.left.equalTo(@(0));

}

make.centerY.equalTo(self.contairView);

make.height.equalTo(self.contairView.mas_height);

make.width.equalTo(self.contairView.mas_height);

}];

UILabel*subLabel = [UILabelnew];

subLabel.font= [UIFontsystemFontOfSize:38];

[subViewaddSubview:subLabel];

[subLabelmas_makeConstraints:^(MASConstraintMaker*make) {

make.centerX.equalTo(subView);

make.centerY.equalTo(subView);

}];

lastView = subView;

UIBezierPath*path = [UIBezierPathbezierPathWithRect:CGRectMake((CGRectGetHeight(self.frame)-2)/2,5,2,(CGRectGetHeight(self.frame)-10))];

CAShapeLayer*line = [CAShapeLayerlayer];

line.path= path.CGPath;

line.fillColor=_viewColorHL.CGColor;

[subView.layeraddSublayer:line];

if(i ==0) {//初始化第一個view為選擇狀態(tài)

[lineaddAnimation:[selfopacityAnimation]forKey:@"kOpacityAnimation"];

line.hidden=NO;

subView.borderColor=_viewColorHL;

}else{

line.hidden=YES;

subView.borderColor=_viewColor;

}

[self.viewArraddObject:subView];

[self.labelArraddObject:subLabel];

[self.pointlineArraddObject:line];

}

[_contairViewmas_makeConstraints:^(MASConstraintMaker*make) {

make.right.equalTo(lastView?lastView.mas_right:@(0));

}];

}

#pragma mark - TextView

-(void)beginEdit{

[self.textViewbecomeFirstResponder];

}

-(void)endEdit{

[self.textViewresignFirstResponder];

}

- (void)textViewDidChange:(UITextView*)textView{

NSLog(@"%@",textView.text);

NSString*verStr = textView.text;

//有空格去掉空格

verStr = [verStrstringByReplacingOccurrencesOfString:@" "withString:@""];

if(verStr.length>=_maxLenght) {

verStr = [verStrsubstringToIndex:_maxLenght];

[selfendEdit];

}

textView.text= verStr;

if(self.block) {

//將textView的值傳出去

self.block(verStr);

}

for(inti=0; i

//以text為中介區(qū)分

UILabel*label =self.labelArr[i];

if(i

[selfchangeViewLayerIndex:ipointHidden:YES];

label.text= [verStrsubstringWithRange:NSMakeRange(i,1)];

}else{

[selfchangeViewLayerIndex:ipointHidden:i==verStr.length?NO:YES];

if(!verStr&&verStr.length==0) {//textView的text為空的時候

[selfchangeViewLayerIndex:0pointHidden:NO];

}

label.text=@"";

}

}

}

- (void)changeViewLayerIndex:(NSInteger)index pointHidden:(BOOL)hidden{

UIView*view =self.viewArr[index];

view.borderColor= hidden?_viewColor:_viewColorHL;

CAShapeLayer*line =self.pointlineArr[index];

if(hidden) {

[lineremoveAnimationForKey:@"kOpacityAnimation"];

}else{

[lineaddAnimation:[selfopacityAnimation]forKey:@"kOpacityAnimation"];

}

line.hidden= hidden;

}

- (CABasicAnimation*)opacityAnimation {

CABasicAnimation*opacityAnimation = [CABasicAnimationanimationWithKeyPath:@"opacity"];

opacityAnimation.fromValue=@(1.0);

opacityAnimation.toValue=@(0.0);

opacityAnimation.duration=0.9;

opacityAnimation.repeatCount=HUGE_VALF;

opacityAnimation.removedOnCompletion=YES;

opacityAnimation.fillMode=kCAFillModeForwards;

opacityAnimation.timingFunction=[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseIn];

returnopacityAnimation;

}

#pragma mark --setter&&getter

-(void)setMaxLenght:(NSInteger)maxLenght{

_maxLenght= maxLenght;

}

-(void)setKeyBoardType:(UIKeyboardType)keyBoardType{

_keyBoardType= keyBoardType;

self.textView.keyboardType= keyBoardType;

}

-(void)setViewColor:(UIColor*)viewColor{

_viewColor= viewColor;

}

-(void)setViewColorHL:(UIColor*)viewColorHL{

_viewColorHL= viewColorHL;

}

-(UITextView*)textView{

if(!_textView) {

_textView= [UITextViewnew];

_textView.tintColor= [UIColorclearColor];

_textView.backgroundColor= [UIColorclearColor];

_textView.textColor= [UIColorclearColor];

_textView.delegate=self;

_textView.keyboardType=UIKeyboardTypeDefault;

_textView.autocorrectionType=UITextAutocorrectionTypeNo;//取消自動聯(lián)想功能

}

return_textView;

}

-(NSMutableArray*)pointlineArr{

if(!_pointlineArr) {

_pointlineArr= [NSMutableArraynew];

}

return_pointlineArr;

}

-(NSMutableArray*)viewArr{

if(!_viewArr) {

_viewArr= [NSMutableArraynew];

}

return_viewArr;

}

-(NSMutableArray*)labelArr{

if(!_labelArr) {

_labelArr= [NSMutableArraynew];

}

return_labelArr;

}

@end



4.自定義文件寫好后绸狐,在你需要使用的地方調(diào)用即刻~

定義外部屬性,

MQVerCodeInputView*verView;//自定義驗(yàn)證碼

NSString*code;//輸入的驗(yàn)證碼


點(diǎn)擊圖形驗(yàn)證碼突琳,調(diào)用此方法 ? 傳入后臺請求的圖片劫窒,轉(zhuǎn)成NSData*類型。

#pragma mark -彈出驗(yàn)證碼輸入框

-(void)showGraphicalVerificationCode:(NSData*)data{

[self tapBut];

maskView= [[UIViewalloc]initWithFrame:CGRectMake(0,0,SCREENWIDTH,SCREENHEIGHT)];

maskView.backgroundColor= [UIColorblackColor];

maskView.alpha=0.5;

[self.viewaddSubview:maskView];

UITapGestureRecognizer*tapGesture = [[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(tapBut)];

[maskViewaddGestureRecognizer:tapGesture];

imageBtn= [[UIButtonalloc]initWithFrame:CGRectMake(0,0,SCREENWIDTH-50-80,60)];

imageBtn.centerX=maskView.centerX;

imageBtn.centerY=maskView.centerY-80;

imageBtn.layer.masksToBounds=YES;

imageBtn.layer.cornerRadius=4;

[imageBtnsetBackgroundImage:[UIImageimageWithData:data]forState:UIControlStateNormal];

[imageBtnaddTarget:selfaction:@selector(ImageChange:)forControlEvents:UIControlEventTouchUpInside];

[self.viewaddSubview:imageBtn];

__weaktypeof(self) weakSelf =self;

verView= [[MQVerCodeInputViewalloc]initWithFrame:CGRectMake(0,0,SCREENWIDTH-50-80,50)];

verView.maxLenght=4;//最大長度

verView.keyBoardType=UIKeyboardTypePhonePad;

[verViewmq_verCodeViewWithMaxLenght];

verView.block= ^(NSString*text){

NSLog(@"text = %@",text);

if(text.length==4) {

labelText= text;

[weakSelfgetPhoneVerificationCode];

}

};

verView.center=maskView.center;

[self.viewaddSubview:verView];

}


#pragma mark -移除驗(yàn)證碼輸入框

-(void)tapBut{

[maskViewremoveFromSuperview];

[verViewremoveFromSuperview];

[imageBtnremoveFromSuperview];

}


附上github ?圖形驗(yàn)證碼Demo地址https://github.com/xuliang0712/iOS-.git

如有問題冠息,歡迎交流~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逛艰,一起剝皮案震驚了整個濱河市搞旭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肄渗,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欠动,死亡現(xiàn)場離奇詭異惑申,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)人芽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門绩脆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來橄抹,“玉大人祈坠,你說我怎么就攤上這事赦拘》页粒” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵丸逸,是天一觀的道長。 經(jīng)常有香客問我捎谨,道長憔维,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任检吆,我火速辦了婚禮程储,結(jié)果婚禮上医舆,老公的妹妹穿的比我還像新娘横浑。我一直安慰自己徒坡,他們只是感情好涧团,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布环凿。 她就那樣靜靜地躺著集嵌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪根欧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天凤粗,我揣著相機(jī)與錄音今豆,去河邊找鬼。 笑死呆躲,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的插掂。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼辅甥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了璃弄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤夏块,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后纤掸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡患民,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了匹颤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡印蓖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赦肃,到底是詐尸還是另有隱情,我是刑警寧澤公浪,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站厅各,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏预柒。R本人自食惡果不足惜袁梗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一憔古、第九天 我趴在偏房一處隱蔽的房頂上張望遮怜。 院中可真熱鬧鸿市,春花似錦锯梁、人聲如沸焰情。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谒获,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間批狱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工赔硫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盐肃。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像砸王,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子谦铃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容

  • iOS_autoLayout_Masonry 概述 Masonry是一個輕量級的布局框架與更好的包裝AutoLay...
    指尖的跳動閱讀 1,153評論 1 4
  • 一、前言 關(guān)于蘋果的布局一直是我比較糾結(jié)的問題驹闰,是寫代碼來控制布局,還是使用storyboard來控制布局呢嘹朗?以前...
    iplaycodex閱讀 2,440評論 0 1
  • 1.NSTimer //暫停if ([timer isValid]) {[timer setFireDate:[N...
    俊月閱讀 1,311評論 0 0
  • (一)Masonry介紹 Masonry是一個輕量級的布局框架 擁有自己的描述語法 采用更優(yōu)雅的鏈?zhǔn)秸Z法封裝自動布...
    木易林1閱讀 2,320評論 0 3
  • 我家30張全家福 容月 從結(jié)婚到現(xiàn)在,我們已照了30張結(jié)婚周年照疆栏。最近有同事要看曾掂,我便與她們一起仔細(xì)看了一遍壁顶,發(fā)現(xiàn)...
    容月閱讀 339評論 0 2