本地验证码
每日一浪,总结下相关验证码实现方法,我是用UIView来实现验证码的,也可以使用button
.h文件:
// Copyright © 2016年 刘勇虎. All rights reserved. // #import <UIKit/UIKit.h> @interface VerifiactionCodeView : UIView @property(nonatomic,strong)NSString *verificationCodeText; @end
.m文件:
1 // Copyright © 2016年 刘勇虎. All rights reserved. 2 // 3 4 #import "VerifiactionCodeView.h" 5 6 @implementation VerifiactionCodeView 7 8 -(instancetype)initWithFrame:(CGRect)frame{ 9 if (self == [super initWithFrame:frame]) { 10 // self.backgroundColor = [UIColor whiteColor]; 11 12 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(getVerifiactionCodeVew)]; 13 14 [self addGestureRecognizer:tap]; 15 } 16 17 return self; 18 } 19 20 - (void)getVerifiactionCodeVew{ 21 // 重新绘制 22 [self setNeedsDisplay]; 23 } 24 25 26 // Only override drawRect: if you perform custom drawing. 27 // An empty implementation adversely affects performance during animation. 28 - (void)drawRect:(CGRect)rect { 29 [super drawRect:rect]; 30 31 32 float red = arc4random() % 100 / 100.0; 33 float green = arc4random() % 100 / 100.0; 34 float blue = arc4random() % 100 / 100.0; 35 36 UIColor *color = [UIColor colorWithRed:red green:green blue:blue alpha:0.3]; 37 [self setBackgroundColor:color]; 38 39 40 NSString *text = [NSString stringWithFormat:@"%@",@"1234"]; 41 _verificationCodeText = text; 42 CGSize cSize = [@"A" sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20]}]; 43 44 int width = rect.size.width / text.length - cSize.width; 45 int height = rect.size.height - cSize.height; 46 CGPoint point; 47 48 NSArray *colorArr = @[[UIColor redColor],[UIColor orangeColor],[UIColor cyanColor],[UIColor blueColor]]; 49 50 float pX, pY; 51 for (int i = 0; i < text.length; i++) 52 { 53 pX = arc4random() % width + rect.size.width / text.length * i; 54 pY = arc4random() % height; 55 point = CGPointMake(pX, pY); 56 unichar c = [text characterAtIndex:i]; 57 NSString *textC = [NSString stringWithFormat:@"%C", c]; 58 59 int j = arc4random()%4; 60 [textC drawAtPoint:point withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20],NSForegroundColorAttributeName:colorArr[j]} ]; 61 62 red = arc4random() % 100 / 100.0; 63 green = arc4random() % 100 / 100.0; 64 blue = arc4random() % 100 / 100.0; 65 66 color = [UIColor colorWithRed:red green:green blue:blue alpha:0.3]; 67 [self setBackgroundColor:color]; 68 NSLog(@"==%@",textC); 69 } 70 71 CGContextRef context = UIGraphicsGetCurrentContext(); 72 CGContextSetLineWidth(context, 1.0); 73 for(int cout = 0; cout < 10; cout++) 74 { 75 red = arc4random() % 100 / 100.0; 76 green = arc4random() % 100 / 100.0; 77 blue = arc4random() % 100 / 100.0; 78 79 80 color = [UIColor colorWithRed:red green:green blue:blue alpha:0.2]; 81 CGContextSetStrokeColorWithColor(context, [color CGColor]); 82 pX = arc4random() % (int)rect.size.width; 83 pY = arc4random() % (int)rect.size.height; 84 CGContextMoveToPoint(context, pX, pY); 85 pX = arc4random() % (int)rect.size.width; 86 pY = arc4random() % (int)rect.size.height; 87 CGContextAddLineToPoint(context, pX, pY); 88 CGContextStrokePath(context); 89 90 91 } 92 }
相关知识点:
1,UIView的setNeedsDisplay和setNeedsLayout方法
首先两个方法都是异步执行的。而setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到 UIGraphicsGetCurrentContext,就可以画画了。而setNeedsLayout会默认调用layoutSubViews,就可以 处理子视图中的一些数据。综上所诉,setNeedsDisplay方便绘图,而layoutSubViews方便出来数据。
layoutSubviews在以下情况下会被调用:1、init初始化不会触发layoutSubviews。
2、addSubview会触发layoutSubviews。
3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。
4、滚动一个UIScrollView会触发layoutSubviews。
5、旋转Screen会触发父UIView上的layoutSubviews事件。
6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。7、直接调用setLayoutSubviews。drawRect在以下情况下会被调用:1、如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。drawRect调用是在Controller->loadView, Controller->viewDidLoad 两方法之后掉用的.所以不用担心在控制器中,这些View的drawRect就开始画了.这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量值).
2、该方法在调用sizeToFit后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。
3、通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。
4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。
以上1,2推荐;而3,4不提倡drawRect方法使用注意点:1、若使用UIView绘图,只能在drawRect:方法中获取相应的contextRef并绘图。如果在其他方法中获取将获取到一个 invalidate的ref并且不能用于画图。drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay 或者 setNeedsDisplayInRect,让系统自动调该方法。
2、若使用calayer绘图,只能在drawInContext: 中(类似于drawRect)绘制,或者在delegate中的相应方法绘制。同样也是调用setNeedDisplay等间接调用以上方法
3、若要实时画图,不能使用gestureRecognizer,只能使用touchbegan等方法来掉用setNeedsDisplay实时刷新屏幕