zoukankan      html  css  js  c++  java
  • iPhone:iOS界面,本地生成随机验证码

    本文博客,模仿杰瑞教育的一篇博文,并在它的基础上,进行了些许更改。同时在重写的过程中,对自己忽略的地方,进行了重新认识,受益匪浅。文章来源:http://www.cnblogs.com/jerehedu/p/4527707.html

    其实这个功能,并不是很实用,但是,对于我们梳理细小的知识点,还是很有必要的。

    一,首先,我们需要自定义一个view,这样,我们将图形绘制在里面,init这个view的时候,就可以直接显示了,以后再遇到,就可以“拿来主义”了。

     codeView.h 

    @property(nonatomic, strong)NSMutableString * changeString;//存放验证码的字符串

     我们需要一个public的参数,便于在外面引用的时候,直接读取。这个用来存放:系统生成的验证码。在输入的时候,我们直接用输入的字符串,和changeString直接进行比较即可。

    codeView.m

    #define kRandomColor [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1.0];

    #define kLineCount 6

    #define kLineWidth 1.0

    #define kCharCount 6

    #define kFontSize [UIFont systemFontOfSize:arc4random()%5 + 15]

    宏定义一些经常用的参数,这样,就不必写后面的代码了。

    在.m里面写.h的私有变量,用来存储字符数组

    @interface codeView(){

        NSArray * changeArray;//字符素材数组

    }

    @end

    接下来,设置view的初始界面,也就是刚进入view的时候,出现的内容

    -(instancetype)initWithFrame:(CGRect)frame{

        if (self = [super initWithFrame:frame]) {

            self.layer.masksToBounds = YES;//隐藏边界

            self.backgroundColor = kRandomColor;

            

            //显示一个随机验证码

            [self changeCaptcha];

        }

        return self;

    }

     重写init方法,这样,就会在系统init的时候,显示出来。

    //获取6个要显示的字符和数字

    -(void)changeCaptcha{

        changeArray = [[NSArray alloc]initWithObjects:@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T",@"U",@"V",@"W",@"X",@"Y",@"Z",@"a",@"b",@"c",@"d",@"e",@"f",@"g",@"h",@"i",@"j",@"k",@"l",@"m",@"n",@"o",@"p",@"q",@"r",@"s",@"t",@"u",@"v",@"w",@"x",@"y",@"z", nil];

        _changeString = [[NSMutableString alloc]initWithCapacity:kCharCount];

        NSString * getStr = [[NSString alloc]init];

        

        for (int i = 0; i < kCharCount; i++) {

            NSInteger index = arc4random()%(changeArray.count-1);

            getStr = [changeArray objectAtIndex:index];

            _changeString = (NSMutableString *)[_changeString stringByAppendingString:getStr];

        }

    }

    //设置点击,更好验证码的方法

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

        [self changeCaptcha];

        [self setNeedsDisplay];

    }

     //画背景图和干扰线

    -(void)drawRect:(CGRect)rect{

        [super drawRect:rect];

        self.backgroundColor = kRandomColor;

        

        //获得要显示验证码字符串,根据长度,计算每个字符显示的大概位置

        CGSize csize = [@"S" sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20]}];

        int width = rect.size.width/_changeString.length-csize.width;

        int height = rect.size.height-csize.height;

        CGPoint point;

        

        //一次绘制每一个字符,可以设置显示的每个字符的字体大小、颜色、样式

        float pX,pY;

        for (int i = 0; i < _changeString.length; i++) {

            pX = arc4random() % width + rect.size.width/_changeString.length*i;

            pY = arc4random()%height;

            

            point = CGPointMake(pX, pY);

            unichar c = [_changeString characterAtIndex:i];

            NSString * textC = [NSString stringWithFormat:@"%c",c];

            [textC drawAtPoint:point withAttributes:@{NSFontAttributeName:kFontSize}];

            

        }

        

        //取得栈顶的CGContextRef

        CGContextRef  context = UIGraphicsGetCurrentContext();

        CGContextSetLineWidth(context, kLineWidth);

        

        //绘制干扰的彩色直线

        for (int i = 0; i < kLineCount; i++) {

            CGFloat components[] = {arc4random()%255/255.0,arc4random()%255/255.0,arc4random()%255/255.0,arc4random()%255/255.0};

            CGContextSetStrokeColor(context, components);

        //设置起点

            pX = arc4random()%(int)rect.size.width;

            pY = arc4random()%(int)rect.size.height;

            CGContextMoveToPoint(context, pX, pY);

            //设置终点

            pX = arc4random()%(int)rect.size.width;

            pY = arc4random()%(int)rect.size.height;

            CGContextAddLineToPoint(context, pX, pY);

            CGContextStrokePath(context);

            

        }

    }

     字体大小、颜色、符号、距离,都是随机的。

    有一个地方,需要注意的就是:画图,只能在drawRect方法里面写才有效,在其他地方,均没有效果。

    这样,自定义的view就ok了。

    下面,就是如何在ViewController里面显示了。

    在ViewController.h里面:

    @interface ViewController : UIViewController<UITextFieldDelegate,UIAlertViewDelegate>

    @property(nonatomic, retain)codeView * codeView;

    @property(nonatomic, retain)UITextField * inputTextField;

    @end

     要遵循两个代理,UITextFieldDelegate、UIAlertViewDelegate。

    在.m里面,主要是设置显示的坐标,以及键盘隐藏等几种方法

    在viewDidLoad方法里面:

    - (void)viewDidLoad {

        [super viewDidLoad];

        

        self.view.backgroundColor = [UIColor whiteColor];

        

        _codeView = [[codeView alloc]initWithFrame:CGRectMake(20, 40, 150, 40)];

        [self.view addSubview:_codeView];

        

        //提示文字

        UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(190, 40, 100, 40)];

        label.text = @"点击图片换验证码";

        label.font = [UIFont systemFontOfSize:12];

        label.textColor = [UIColor grayColor];

        [self.view addSubview:label];

        

        //添加输入框

        _inputTextField = [[UITextField alloc]initWithFrame:CGRectMake(20, 100, 150, 40)];

        _inputTextField.layer.borderColor = [[UIColor lightGrayColor]CGColor];

        _inputTextField.layer.borderWidth = 2.0;

        _inputTextField.layer.cornerRadius = 5.0;

        _inputTextField.font = [UIFont systemFontOfSize:21];

        _inputTextField.placeholder = @"请输入验证码";

        _inputTextField.clearButtonMode = UITextFieldViewModeWhileEditing;

        _inputTextField.backgroundColor = [UIColor clearColor];

        _inputTextField.textAlignment = NSTextAlignmentCenter;

        _inputTextField.returnKeyType = UIReturnKeyDone;

        _inputTextField.delegate = self;

        [self.view addSubview:_inputTextField];

        

        //添加手势,用来隐藏键盘

        UITapGestureRecognizer * tapGestureRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapToHideTheKeyBoard:)];

        tapGestureRecognizer.cancelsTouchesInView = NO;

        [self.view addGestureRecognizer:tapGestureRecognizer];

        

    }

    两种隐藏键盘的方法

    #pragma mark --Tap

    -(void)tapToHideTheKeyBoard:(UITapGestureRecognizer *)tap{

    //    [_inputTextField resignFirstResponder];

    }

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

        [_inputTextField resignFirstResponder];

    }

    点击键盘的Return消失键盘的方法

    #pragma mark --UITextFieldDelegate

    -(BOOL)textFieldShouldReturn:(UITextField *)textField{

        if ([_inputTextField.text isEqualToString:_codeView.changeString ] || [_inputTextField.text isEqualToString:[_codeView.changeString lowercaseString]]) {

            //弹出正确

            UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:@"恭喜您" message:@"验证成功" delegate:self cancelButtonTitle:@"ok" otherButtonTitles: nil];

            [alertView show];

        }else{

            //验证码不匹配,验证码和输入框晃动

            CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.x"];

            animation.repeatCount = 1;

            animation.values = @[@-20,@20,@-20];

            [_codeView.layer addAnimation:animation forKey:nil];

            [_inputTextField.layer addAnimation:animation forKey:nil];

        }

        return YES;

    }

    点击确定按钮,收回键盘的方法

    #pragma mark --UIAlertViewDelegate

    -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{

        //清空输入框内容,收回键盘

        if (buttonIndex == 0) {

            _inputTextField.text = @"";

            [_inputTextField resignFirstResponder];

        }

    }

     这样,这个功能就完成了。

    这个地方的知识点主要是:

    1.画线;

    2.产生随机产生的字符

    3.让键盘消失

    在原有博客的基础上,增加了不区分大小写的小功能。

  • 相关阅读:
    AcWing 524. 愤怒的小鸟
    AcWing 算法提高课题解目录
    AcWing 292. 炮兵阵地
    AcWing 798. 差分矩阵
    golang 写数据到excel文件 清明
    使用golang开发mqtt服务压力测试工具 清明
    Linux云服务器安装JDK步骤 清明
    shell monitor memory 清明
    自己实现一个Electron跨进程消息组件(兼新书自荐)
    如何把Electron做成一个Runtime,让多个应用共享同一个Electron
  • 原文地址:https://www.cnblogs.com/tanglimei/p/4539519.html
Copyright © 2011-2022 走看看