iOS 分割输入验证码的视觉效果

97 篇文章 0 订阅
19 篇文章 1 订阅

通常情况下,在用户注册或者登录的时候我们会用到手机验证码,而有时就会需要,分割输入验证码的视觉效果。

那这种情况,我们怎么实现呢?

在网上查了很多,好多都只是给了实现代码,给的东西都不是很详细,粘贴过来,有好多值不知道是从哪里来的,还有的就是需要第三方,但是第三方代码量就太多了,会使程序变大,虽然影响不大,但是完全没有必要

下面时我结合网上和自己实现代码,下面配有demo下载链接

先看实现代码:

我们要创建两个类:VertificationCodeInputView 继承 UIView, VertificationCodeInputLabel 继承UILabel

先看VertificationCodeInputView.h文件

@protocol getTextFieldContentDelegate <NSObject>
//返回搜索内容
-(void)returnTextFieldContent:(NSString*)content;
@end

@interface VertificationCodeInputView : UIView
@property (assign,nonatomic,readwrite)id <getTextFieldContentDelegate>delegate;
/**背景图片*/
@property (nonatomic,copy)NSString *backgroudImageName;
/**验证码/密码的位数*/
@property (nonatomic,assign)NSInteger numberOfVertificationCode;
/**控制验证码/密码是否密文显示*/
@property (nonatomic,assign)bool secureTextEntry;
/**验证码/密码内容,可以通过该属性拿到验证码/密码输入框中验证码/密码的内容*/
@property (nonatomic,copy)NSString *vertificationCode;

-(void)becomeFirstResponder; 

接下来看VertificationCodeInputView.m文件

 

#import "VertificationCodeInputView.h"
#import "VertificationCodeInputLabel.h"

@interface VertificationCodeInputView () <UITextFieldDelegate>
/**用于获取键盘输入的内容,实际不显示*/
@property (nonatomic,strong)UITextField *textField;
/**验证码/密码输入框的背景图片*/
@property (nonatomic,strong)UIImageView *backgroundImageView;
/**实际用于显示验证码/密码的label*/
@property (nonatomic,strong)VertificationCodeInputLabel *label;
@end

@implementation VertificationCodeInputView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // 设置透明背景色,保证vertificationCodeInputView显示的frame为backgroundImageView的frame
        self.backgroundColor = [UIColor clearColor];
        /* 调出键盘的textField */
        _textField = [[UITextField alloc]initWithFrame:self.bounds];
        // 隐藏textField,通过点击IDVertificationCodeInputView使其成为第一响应者,来弹出键盘
        _textField.hidden =YES;
        _textField.keyboardType =UIKeyboardTypeNumberPad;
        _textField.delegate =self;
        _textField.font = [UIFont systemFontOfSize:25];
        // 将textField放到最后边
        [self insertSubview:self.textField atIndex:0];
        /* 添加用于显示验证码/密码的label */
        _label = [[VertificationCodeInputLabel alloc]initWithFrame:self.bounds];
        _label.numberOfVertificationCode =_numberOfVertificationCode;
        _label.secureTextEntry =_secureTextEntry;
        _label.font =self.textField.font;
        [self addSubview:self.label];
    }
    return self;
}

#pragma mark --------- 设置背景图片
- (void)setBackgroudImageName:(NSString *)backgroudImageName {
    _backgroudImageName = backgroudImageName;
    // 若用户设置了背景图片,则添加背景图片
    self.backgroundImageView = [[UIImageView alloc]initWithFrame:self.bounds];
    self.backgroundImageView.image = [UIImage imageNamed:self.backgroudImageName];
    // 将背景图片插入到label的后边,避免遮挡验证码/密码的显示
    [self insertSubview:self.backgroundImageView belowSubview:self.label];
}

- (void)setNumberOfVertificationCode:(NSInteger)numberOfVertificationCode {
    _numberOfVertificationCode = numberOfVertificationCode;
    // 保持label的验证码/密码位数与IDVertificationCodeInputView一致,此时label一定已经被创建
    self.label.numberOfVertificationCode =_numberOfVertificationCode;
}

- (void)setSecureTextEntry:(bool)secureTextEntry {
    _secureTextEntry = secureTextEntry;
    self.label.secureTextEntry =_secureTextEntry;
}

-(void)becomeFirstResponder{
    [self.textField becomeFirstResponder];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self.textField becomeFirstResponder];
}

#pragma mark ------ 时时监测输入框的内容

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    // 判断是不是“删除”字符
    if (string.length !=0) {//不是“删除”字符
        // 判断验证码/密码的位数是否达到预定的位数
        if (textField.text.length <self.numberOfVertificationCode) {
            self.label.text = [textField.text stringByAppendingString:string];
            self.vertificationCode =self.label.text;
            if (self.label.text.length == _numberOfVertificationCode) {
                /******* 通过协议将验证码返回当前页面  ******/
                if ([_delegate respondsToSelector:@selector(returnTextFieldContent:)]){
                    [_delegate returnTextFieldContent:_vertificationCode];
                }
            }
            return YES;
        } else {
            return NO;
        }
    } else {//是“删除”字符
        self.label.text = [textField.text substringToIndex:textField.text.length -1];
        self.vertificationCode =self.label.text;
        return YES;
    }
}
 

在下来就是VertificationCodeInputLabel.h


/**验证码/密码的位数*/
@property (nonatomic,assign)NSInteger numberOfVertificationCode;

/**控制验证码/密码是否密文显示*/
@property (nonatomic,assign)bool secureTextEntry; 

在下来就是.m文件

#import "VertificationCodeInputLabel.h"

//设置边框宽度,值越大,边框越粗
#define ADAPTER_RATE_WIDTH 1
//设置是否有边框,等于 1 时 是下划线  大于1 的时候随着值越大,边框越大,
#define ADAPTER_RATE_HIDTH 1

@implementation VertificationCodeInputLabel

//重写setText方法,当text改变时手动调用drawRect方法,将text的内容按指定的格式绘制到label上
- (void)setText:(NSString *)text {
    [super setText:text];
    // 手动调用drawRect方法
    [self setNeedsDisplay];
}

// 按照指定的格式绘制验证码/密码
- (void)drawRect:(CGRect)rect1 {
    //计算每位验证码/密码的所在区域的宽和高
    CGRect rect =CGRectMake(0,0,200,45);
    float width = rect.size.width / (float)self.numberOfVertificationCode;
    float height = rect.size.height;
    // 将每位验证码/密码绘制到指定区域
    for (int i =0; i <self.text.length; i++) {
        // 计算每位验证码/密码的绘制区域
        CGRect tempRect =CGRectMake(i * width,0, width, height);
        if (_secureTextEntry) {//密码,显示圆点
            UIImage *dotImage = [UIImage imageNamed:@"dot"];
            // 计算圆点的绘制区域
            CGPoint securityDotDrawStartPoint =CGPointMake(width * i + (width - dotImage.size.width) /2.0, (tempRect.size.height - dotImage.size.height) / 2.0);
            // 绘制圆点
            [dotImage drawAtPoint:securityDotDrawStartPoint];
        } else {//验证码,显示数字
            // 遍历验证码/密码的每个字符
            NSString *charecterString = [NSString stringWithFormat:@"%c", [self.text characterAtIndex:i]];

            // 设置验证码/密码的现实属性

            NSMutableDictionary *attributes = [[NSMutableDictionary alloc]init];

            attributes[NSFontAttributeName] =self.font;

            // 计算每位验证码/密码的绘制起点(为了使验证码/密码位于tempRect的中部,不应该从tempRect的重点开始绘制)
            // 计算每位验证码/密码的在指定样式下的size
            CGSize characterSize = [charecterString sizeWithAttributes:attributes];
            CGPoint vertificationCodeDrawStartPoint =CGPointMake(width * i + (width - characterSize.width) /2.0, (tempRect.size.height - characterSize.height) /2.0);
            // 绘制验证码/密码
            [charecterString drawAtPoint:vertificationCodeDrawStartPoint withAttributes:attributes];
        }
    }

    //绘制底部横线
    for (int k=0; k<self.numberOfVertificationCode; k++) {
        [self drawBottomLineWithRect:rect andIndex:k];
        [self drawSenterLineWithRect:rect andIndex:k];
    }

}

//绘制底部的线条
- (void)drawBottomLineWithRect:(CGRect)rect1 andIndex:(int)k{
    CGRect rect =CGRectMake(0,0,200,45);
    float width = rect.size.width / (float)self.numberOfVertificationCode;
    float height = rect.size.height;
    //1.获取上下文
    CGContextRef context =UIGraphicsGetCurrentContext();
    //2.设置当前上下问路径
    CGFloat lineHidth =0.25 * ADAPTER_RATE_WIDTH;
    CGFloat strokHidth =0.5 * ADAPTER_RATE_HIDTH;
    CGContextSetLineWidth(context, lineHidth);
    if ( k<=self.text.length ) {
        CGContextSetStrokeColorWithColor(context,[UIColor greenColor].CGColor);//底部颜色
        CGContextSetFillColorWithColor(context,[UIColor greenColor].CGColor);//内容的颜色
    }else{
        CGContextSetStrokeColorWithColor(context,[UIColor redColor].CGColor);//底部颜色
        CGContextSetFillColorWithColor(context,[UIColor greenColor].CGColor);//内容的颜色
    }

    CGRect rectangle =CGRectMake(k*width+width/10,height-lineHidth-strokHidth,width-width/5,strokHidth);
    CGContextAddRect(context, rectangle);
    CGContextStrokePath(context);
}

//绘制中间的输入的线条
- (void)drawSenterLineWithRect:(CGRect)rect1 andIndex:(int)k{
    if ( k==self.text.length ) {
        CGRect rect =CGRectMake(0,0,200,45);
        float width = rect.size.width / (float)self.numberOfVertificationCode;
        float height = rect.size.height;
        //1.获取上下文
        CGContextRef context =UIGraphicsGetCurrentContext();
        CGContextSetLineWidth(context,0.5);
        /****  设置竖线的颜色 ****/
        CGContextSetStrokeColorWithColor(context,[UIColor greenColor].CGColor);//
        CGContextSetFillColorWithColor(context,[UIColor greenColor].CGColor);
        CGContextMoveToPoint(context, width * k + (width -1.0) /2.0, height/5);
        CGContextAddLineToPoint(context,  width * k + (width -1.0) /2.0,height-height/5);
        CGContextStrokePath(context);
    }
}


以上这些就是实现代码,接下来是调用

#import "ViewController.h"
#import "VertificationCodeInputView.h"
@interface ViewController ()<getTextFieldContentDelegate>{
    VertificationCodeInputView *vertificationCodeInputView;
}
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    vertificationCodeInputView = [[VertificationCodeInputView alloc]initWithFrame:CGRectMake(50,250,200,45)];
    vertificationCodeInputView.delegate = self;
    /****** 设置验证码/密码的位数默认为四位 ******/ 
    vertificationCodeInputView.numberOfVertificationCode = 6;
    /*********验证码(显示数字)YES,隐藏形势 NO,数字形式**********/ 
    vertificationCodeInputView.secureTextEntry =NO;
    [self.view addSubview:vertificationCodeInputView];
    [vertificationCodeInputView becomeFirstResponder];
}

#pragma mark --------- 获取验证码
-(void)returnTextFieldContent:(NSString *)content{
    NSLog(@"%@================验证码",content);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


CSDN  下载链接:分割验证码 

GitHub下载链接:Swift 加OC版本

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王 哪跑!!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值