zoukankan      html  css  js  c++  java
  • OC图片滑动验证

    没事逛cocoaChina的时候有人问图片验证码怎么做,我看了下,网上有很多第三方的框架,但好多都是收费的,所以考虑自己能否做一个,该封装有点简陋,不过可以根据自己需要自行修改

    该代码用到的技术,UIBezierPath可以参考我的另外一篇博客、还UIProgressView的第二次封装、还有手势,这个我之前也有写过博客,和这个大同小异

    效果图:

     需要用到的代码:

     CustomProgressView是对UIProgressView的封装,可以通过拖动滑块改变进度条value值,这个地方我用的是一个UILabel,有点难看,后期可以根据自己的需要改为图片,楼主的原则是'只要能用其他的控件代替,就不用图片'

    CustomProgressView.h

    #import <UIKit/UIKit.h>
    
    @interface CustomProgressView : UIView
    /**
     progress的value值 isEnd是否停止滑动
     */
    @property(nonatomic,copy)void(^blockProgressValue)(float value,BOOL isEnd);
    -(void)setProgress:(float)progress;
    @end
    

     CustomProgressView.m

    #import "CustomProgressView.h"
    
    @interface CustomProgressView ()
    @property(nonatomic,strong)UIProgressView *preView;
    @property(nonatomic,strong)UILabel *trackLab;
    @end
    
    @implementation CustomProgressView
    
    -(instancetype)initWithFrame:(CGRect)frame{
        self = [super initWithFrame:frame];
        if(self){
            self.preView = [[UIProgressView alloc]initWithFrame:CGRectMake(0, frame.size.height/2.0, frame.size.width, 1)];
            self.preView.progressTintColor = [UIColor redColor];
            self.preView.trackTintColor = [UIColor grayColor];
            [self addSubview:self.preView];
            
            self.trackLab = [[UILabel alloc]initWithFrame:CGRectMake(0,frame.size.height/2.0-10, 20, 20)];
            self.trackLab.backgroundColor = [UIColor redColor];
            self.trackLab.userInteractionEnabled = YES;
            [self addSubview:self.trackLab];
        }
        return self;
    }
    -(void)setProgress:(float)progress{
        float x = self.bounds.size.width * progress;
        CGRect rect = self.trackLab.frame;
        rect.origin.x = x;
        self.trackLab.frame = rect;
        [self.preView setProgress:progress];
    }
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    }
    -(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        UITouch *touch = [touches anyObject];
        if([touch.view isKindOfClass:[UILabel class]]){
            CGPoint point = [touch locationInView:[touch.view superview]];
            float x = point.x;
            CGRect rect = self.trackLab.frame;
            if(x < 0 ){
                rect.origin.x = 0;
                self.trackLab.frame = rect;
                
                return;
            }
            if(x > self.bounds.size.width-20){
                rect.origin.x = self.bounds.size.width-20;
                self.trackLab.frame = rect;
                return;
            }
            rect.origin.x = x;
            self.trackLab.frame = rect;
            [self.preView setProgress:x/self.bounds.size.width];
            if(self.blockProgressValue){
                self.blockProgressValue(x/self.bounds.size.width,NO);
            }
        }
    }
    
    -(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        UITouch *touch = [touches anyObject];
        if([touch.view isKindOfClass:[UILabel class]]){
            if(self.blockProgressValue){
                self.blockProgressValue(self.preView.progress,YES);
            }
        }
        
    }
    
    
    @end
    

    ImageLockView.h

    #import <UIKit/UIKit.h>
    
    @interface ImageLockView : UIView
    -(void)show;
    -(void)hidden;
    @end
    

     ImageLockView.m

    #import "ImageLockView.h"
    #import "CustomProgressView.h"
    //屏幕的宽度
    #define ScreenWidth  [UIScreen mainScreen].bounds.size.width
    //屏幕的高度
    #define ScreenHeight  [UIScreen mainScreen].bounds.size.height
    //内容的宽度
    #define ContentWidth 200
    //内容的高度
    #define ContentHeight 230
    //间距
    #define Margin 10
    @interface ImageLockView (){
        CGRect frontRect;//
    }
    /**半透明背景蒙版*/
    @property(nonatomic,strong)UIView *backView;
    /**内容view,白的的圆角矩形*/
    @property(nonatomic,strong)UIView *contentView;
    /**底下一层的Img*/
    @property(nonatomic,strong)UIImageView *backImg;
    /**滑动Img*/
    @property(nonatomic,strong)UIImageView *frontImg;
    /***最下方可以滑动的ProgressView*/
    @property(nonatomic,strong)CustomProgressView *progressView;
    @end
    
    @implementation ImageLockView
    
    - (instancetype)initWithFrame:(CGRect)frame{
        frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight);
        self = [super initWithFrame:frame];
        if(self){
           
            self.backView = [[UIView alloc]initWithFrame:self.bounds];
            self.backView.backgroundColor = [UIColor blackColor];
            
            [self addSubview:self.backView];
            
            
            self.contentView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, ContentWidth, ContentHeight)];
            self.contentView.backgroundColor = [UIColor whiteColor];
            self.contentView.layer.cornerRadius = 8.0f;
            self.contentView.center = self.center;
            [self addSubview:self.contentView];
            
            
            self.backImg = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"WechatIMG"]];
            self.frontImg = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"WechatIMG"]];
            
            self.backImg.frame = CGRectMake(Margin, Margin, ContentWidth-Margin*2, ContentWidth-Margin*2);
            self.frontImg.frame = CGRectMake(Margin, Margin, ContentWidth-Margin*2, ContentWidth-Margin*2);
            [self.contentView addSubview:self.backImg];
            [self.contentView addSubview:self.frontImg];
            
            self.progressView = [[CustomProgressView alloc]initWithFrame:CGRectMake(Margin, CGRectGetMaxY(self.backImg.frame)+Margin, ContentWidth-Margin*2, Margin*2)];
            [self.contentView addSubview:self.progressView];
            __block typeof(self)weakSelf = self;
            self.progressView.blockProgressValue = ^(float value,BOOL isEnd) {
                if(isEnd){
                    //这个地方判断5只是为了给滑动的图片一个容错性,偏离5个像素也判断是对的
                    CGRect frontRect = weakSelf.frontImg.frame;
                    CGRect backRect = weakSelf.backImg.frame;
                    if(frontRect.origin.x-backRect.origin.x < 5 && frontRect.origin.x-backRect.origin.x > -5){
                        //成功了移除
                        [weakSelf hidden];
                    }else{
                        //失败了刷新继续拼图
                       
                        [weakSelf refreshView];
                    }
                   
                }else{
                    float width = frame.size.width * value;
                    CGRect rect = weakSelf.frontImg.frame;
                    rect.origin.x = self->frontRect.origin.x+width;
                    
                    weakSelf.frontImg.frame = rect;
                }
               
            };
    
            
            [self refreshView];
            
        }
        return self;
    }
    /**
     刷新当前界面
     */
    -(void)refreshView{
        //刷新的时候progressView的值为0,设置到原始值
         [self.progressView setProgress:0];
        //如果self.backImg上有上次停留的Layer,则删除
        for(CALayer *layer in [self.backImg.layer sublayers]){
            [layer removeFromSuperlayer];
        }
        
        int width = self.backImg.frame.size.width - 40;
        //x-50的原因以及height-40是不想让模块出现在边框之外
        int x = arc4random() % width ;
        if(x < 50){
            x = 50;
        }
        int height = self.backImg.frame.size.height - 40;
        int y = arc4random() % height;
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        shapeLayer.path = [self getPath].CGPath;
        [shapeLayer setFillColor:[UIColor whiteColor].CGColor];
        shapeLayer.frame = CGRectMake(x, y, 36, 36);
        [self.backImg.layer addSublayer:shapeLayer];
        //-x+Margin是因为backImg前面有Margin个空白间距
        frontRect = CGRectMake(-x+Margin, self.backImg.frame.origin.y, self.backImg.frame.size.width, self.backImg.frame.size.height);
        self.frontImg.frame = frontRect;
        UIBezierPath *path = [self getPath];
        CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
        [path applyTransform: transform];
        CAShapeLayer *maskLayer = [CAShapeLayer layer];
        maskLayer.path = path.CGPath;
    
        self.frontImg.layer.mask = maskLayer;
    }
    
    -(void)show{
        UIWindow *window = [[UIApplication sharedApplication]keyWindow];
        [window addSubview:self];
        __block typeof(self)weakSelf = self;
        [UIView animateWithDuration:.5f animations:^{
            weakSelf.backView.alpha = .3f;
        }];
    }
    -(void)hidden{
        __block typeof(self)weakSelf = self;
        [UIView animateWithDuration:.5f animations:^{
            CGRect rect = weakSelf.frame;
            rect.size.height = 0;
            weakSelf.frame = rect;
            weakSelf.alpha = 0;
        } completion:^(BOOL finished) {
            [weakSelf removeFromSuperview];
        }];
    }
    
    
    //画蒙版的形状
    -(UIBezierPath *)getPath{
        UIBezierPath * path = [UIBezierPath bezierPath];
        [path moveToPoint:CGPointMake(0.f, 4.0f)];
        [path addLineToPoint:CGPointMake(12.f, 4.0f)];
        [path addArcWithCenter:CGPointMake(16.f,4.0f) radius:4.0 startAngle:M_PI endAngle:2*M_PI clockwise:YES];
        [path addLineToPoint:CGPointMake(32.f, 4.0f)];
        [path addLineToPoint:CGPointMake(32.f, 12.f)];
        [path addArcWithCenter:CGPointMake(32.f,20.f) radius:4.0 startAngle:1.5*M_PI endAngle:2.5*M_PI clockwise:YES];
        [path addLineToPoint:CGPointMake(32.f, 36.f)];
        [path addLineToPoint:CGPointMake(24.f, 36.f)];
        [path addArcWithCenter:CGPointMake(16.f,36.f) radius:4.0 startAngle:2*M_PI endAngle:M_PI clockwise:NO];
        [path addLineToPoint:CGPointMake(0.f, 36.f)];
        [path addLineToPoint:CGPointMake(0.f, 28.f)];
        [path addArcWithCenter:CGPointMake(0.f,20.f) radius:4.0 startAngle:2.5*M_PI endAngle:1.5*M_PI clockwise:NO];
        [path closePath];
        return path;
    }
    @end
    

     使用

  • 相关阅读:
    [Linux] Ubuntu Server18 python3.7 虚拟环境
    [Linux] 树莓派编译python3.7.4
    [Linux] TMUX Python版本设置
    Linux 批量杀进程的命令
    arm树莓派Raspbian 下安装selenium+chrome
    树莓派Raspbian系统密码
    mac 终端查看端口命令
    selenium firefox 内存 速度优化
    [Linux] tmux 终端复用命令行工具
    通过 ssh 登录到手机 Termux
  • 原文地址:https://www.cnblogs.com/hualuoshuijia/p/10081155.html
Copyright © 2011-2022 走看看