美文网首页iOS开发技巧iOS DeveloperiOS小项目
iOS获取验证码按钮的简单实现

iOS获取验证码按钮的简单实现

作者: 静花寒 | 来源:发表于2016-10-25 14:41 被阅读470次

    开发中,获取验证码的按钮应该比较常见,但大多app的验证码按钮都有一个小小的bug,开发者并不会在意,那就是:

    当点击按钮后,按钮进入倒计时,此时用户选择不留在页面等待,跳转到其他页面,然后收到验证码后,再返回页面进行输入。那么,此时的按钮是否依旧在进行倒计时呢???

    今天我就写了一个封装,解决一下这个bug。思想很简单:单例!
    老规矩,没图说**,丢效果图:

    sms1.gif sms2.gif

    然后是具体实现的代码,拷贝就可以了😄

    //
    //  SmsButtonHandle.h
    //  My Tool
    //
    //  Created by wuwj on 2016/10/25.
    //  Copyright © 2016年 wuwj. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    @interface SmsButtonHandle : NSObject
    //验证码按钮单例封装
    + (instancetype)sharedSmsBHandle;
    
    - (UIButton *)buttonWithFrame:(CGRect)frame title:(NSString *)title action:(SEL)action superVC:(UIViewController *)superVC;
    
    - (void)startTimer;
    @end
    
    //
    //  SmsButtonHandle.m
    //  My Tool
    //
    //  Created by wuwj on 2016/10/25.
    //  Copyright © 2016年 wuwj. All rights reserved.
    //
    
    #import "SmsButtonHandle.h"
    #import "BaseDefinition.h"
    @implementation SmsButtonHandle{
        NSTimeInterval timeInterval;
        UIButton *smsButton;
        NSString *authTitle;
        NSTimer *timer;
        BOOL isFired;
    }
    
    + (instancetype)sharedSmsBHandle{
        static dispatch_once_t onceToken;
        static SmsButtonHandle *handle;
        
        dispatch_once(&onceToken, ^{
            handle = [[SmsButtonHandle alloc] init];
        });
        return handle;
    }
    
    - (UIButton *)buttonWithFrame:(CGRect)frame title:(NSString *)title action:(SEL)action superVC:(UIViewController *)superVC{
        [[SmsButtonHandle sharedSmsBHandle] timeInterval];
        smsButton = [UIButton buttonWithType:(UIButtonTypeCustom)];
        smsButton.frame = frame;
        [smsButton addTarget:superVC action:action forControlEvents:(UIControlEventTouchUpInside)];
        if ([[SmsButtonHandle sharedSmsBHandle] timeInterval] < 59) {
            [[SmsButtonHandle sharedSmsBHandle] startTimer];
        }else{
            [smsButton setTitle:title forState:(UIControlStateNormal)];
        }
        [[SmsButtonHandle sharedSmsBHandle] authTitle:title];
        [smsButton setTitleColor:[UIColor blackColor] forState:(UIControlStateNormal)];
        
        return smsButton;
    }
    
    - (NSString *)authTitle:(NSString *)title{
        if (!authTitle) {
            authTitle = title;
        }
        return authTitle;
    }
    
    - (NSTimeInterval)timeInterval{
        if (!timeInterval) {
            timeInterval = 59;
        }
        return timeInterval;
    }
    
    - (NSTimer *)timer{
        if (!timer) {
            timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
            [timer setFireDate:[NSDate distantFuture]];
        }
        return timer;
    }
    
    #pragma mark - Timer Action
    - (void)timerAction{
        if (timeInterval >= 1) {
            [smsButton setTitle:[authTitle stringByAppendingString:[NSString stringWithFormat:@"(%@)",@(timeInterval--)]] forState:UIControlStateNormal];
            smsButton.backgroundColor = [UIColor lightGrayColor];
            smsButton.userInteractionEnabled = NO;
        }else{
            [self stopTimer];
            timeInterval = 59;
            authTitle = @"重新发送";
            smsButton.backgroundColor = UIColorFromRGB(0xe45e39);
            [smsButton setTitle:authTitle forState:UIControlStateNormal];
            smsButton.userInteractionEnabled = YES;
        }
    }
    
    #pragma mark - Private Method
    - (void)startTimer{
        isFired = YES;
        [self.timer setFireDate:[NSDate date]];
    }
    
    - (void)stopTimer{
        if (timer) {
            [timer setFireDate:[NSDate distantFuture]];
            isFired = NO;
        }
    }
    
    - (void)endTimer{
        if (timer) {
            timeInterval = 59;
            isFired = NO;
            [timer invalidate];
            timer = nil;
        }
    }
    
    @end
    

    之后的调用就十分简单方便了

    - (void)viewWillAppear:(BOOL)animated{
        self.view.backgroundColor = [UIColor whiteColor];
        
        UIButton *button = [[SmsButtonHandle sharedSmsBHandle] buttonWithFrame:(CGRectMake(100, 100, 200, 100)) title:@"发送短信" action:@selector(buttonAction) superVC:self];
        [self.view addSubview:button ];
    }
    - (void)buttonAction{
        NSLog(@"按钮事件");
    //此处可以先调接口,成功后再调此方法
        [[SmsButtonHandle sharedSmsBHandle] startTimer];
    }
    

    写个文章,浏览器都一直炸,不写了,跑路!!

    相关文章

      网友评论

      • StephenCurry300:有2个问题,1是NSTimer做计时器不准啊,尤其是你还放在主线程里;2是这样做虽然解决了你说的那个问题,但是如果两个页面都有发送验证码那就有问题了(当然这种情况比较少)。
      • any_where:有没有考虑计时器在不同的runloop模式下暂停执行的问题?
        StephenCurry300:@any_where 我昨天看的时候也发现这个问题了,还是用GCD更加准确。
      • graliet:沙发

      本文标题:iOS获取验证码按钮的简单实现

      本文链接:https://www.haomeiwen.com/subject/nnpruttx.html