美文网首页iOS分享的demoiOS高阶UI相关iOS Dev
iOS开发:仿微信、支付宝6位密码输入框

iOS开发:仿微信、支付宝6位密码输入框

作者: First灬DKS | 来源:发表于2016-05-27 10:42 被阅读8851次

开发中我们有时候需要用到设置APP钱包的支付密码,用于安全支付的功能,页面是仿照微信或者是支付宝的6位输入框的的做法,就是看上去有6个UITextField,每一个都是一样大小,这其实是一个假象;

Simulator Screen Shot 2016年5月26日 下午7.51.18.png

我的设计思路是:创建一个UITextField,重点是创建一个哦,然后用5根竖线进行分割,这样就是让我们看到了一个有6个一样的输入框在那里躺着了;你说输入时那个黑点点啊,我们可以通过创建一个正方形的UIView,设置圆角为宽高的一半,就是一个圆了,具体如何在中间显示,就是定义这个黑色圆点的frame啊,让他显示在中间,好了,代码如下:

首先在.h中接收UITextFieldDelegate的代理

#import <UIKit/UIKit.h>

//接收UITextField的代理
@interface SYSafetySetUpController : UIViewController<UITextFieldDelegate>

@end

在.m中,主要就是实现页面的效果:

#import "SYSafetySetUpController.h"
#import "Header.h"

#define kDotSize CGSizeMake (10, 10) //密码点的大小
#define kDotCount 6  //密码个数
#define K_Field_Height 45  //每一个输入框的高度

@interface SYSafetySetUpController ()

@property (nonatomic, strong) UITextField *textField;
@property (nonatomic, strong) NSMutableArray *dotArray; //用于存放黑色的点点

@end

@implementation SYSafetySetUpController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"安全设置";
    self.view.backgroundColor = [UIColor sy_tabBarColor];
    
    [self.view addSubview:self.textField];
    //页面出现时让键盘弹出
    [self.textField becomeFirstResponder];  
    [self initPwdTextField];
}

- (void)initPwdTextField
{
    //每个密码输入框的宽度
    CGFloat width = (Screen_Width - 32) / kDotCount;
    
    //生成分割线
    for (int i = 0; i < kDotCount - 1; i++) {
        UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMinX(self.textField.frame) + (i + 1) * width, CGRectGetMinY(self.textField.frame), 1, K_Field_Height)];
        lineView.backgroundColor = [UIColor sy_grayColor];
        [self.view addSubview:lineView];
    }
    
    self.dotArray = [[NSMutableArray alloc] init];
    //生成中间的点
    for (int i = 0; i < kDotCount; i++) {
        UIView *dotView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMinX(self.textField.frame) + (width - kDotCount) / 2 + i * width, CGRectGetMinY(self.textField.frame) + (K_Field_Height - kDotSize.height) / 2, kDotSize.width, kDotSize.height)];
        dotView.backgroundColor = [UIColor blackColor];
        dotView.layer.cornerRadius = kDotSize.width / 2.0f;
        dotView.clipsToBounds = YES;
        dotView.hidden = YES; //先隐藏
        [self.view addSubview:dotView];
        //把创建的黑色点加入到数组中
        [self.dotArray addObject:dotView];
    }
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSLog(@"变化%@", string);
    if([string isEqualToString:@"\n"]) {
        //按回车关闭键盘
        [textField resignFirstResponder];
        return NO;
    } else if(string.length == 0) {
        //判断是不是删除键
        return YES;
    }
    else if(textField.text.length >= kDotCount) {
        //输入的字符个数大于6,则无法继续输入,返回NO表示禁止输入
        NSLog(@"输入的字符个数大于6,忽略输入");
        return NO;
    } else {
        return YES;
    }
}

/**
 *  清除密码
 */
- (void)clearUpPassword
{
    self.textField.text = @"";
    [self textFieldDidChange:self.textField];
}

/**
 *  重置显示的点
 */
- (void)textFieldDidChange:(UITextField *)textField
{
    NSLog(@"%@", textField.text);
    for (UIView *dotView in self.dotArray) {
        dotView.hidden = YES;
    }
    for (int i = 0; i < textField.text.length; i++) {
        ((UIView *)[self.dotArray objectAtIndex:i]).hidden = NO;
    }
    if (textField.text.length == kDotCount) {
        NSLog(@"输入完毕");
    }
}

#pragma mark - init

- (UITextField *)textField
{
    if (!_textField) {
        _textField = [[UITextField alloc] initWithFrame:CGRectMake(16, 100, Screen_Width - 32, K_Field_Height)];
        _textField.backgroundColor = [UIColor whiteColor];
        //输入的文字颜色为白色
        _textField.textColor = [UIColor whiteColor];
        //输入框光标的颜色为白色
        _textField.tintColor = [UIColor whiteColor];
        _textField.delegate = self;
        _textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
        _textField.keyboardType = UIKeyboardTypeNumberPad;
        _textField.layer.borderColor = [[UIColor sy_grayColor] CGColor];
        _textField.layer.borderWidth = 1;
        [_textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
    }
    return _textField;
}

如果想要更加完美一些,可以禁止UITextField的粘贴复制功能;在此我提出一个我的方法,创建一个继承与UITextField的类,在.m中实现下面的方法

/**
 * /禁止可被粘贴复制
 */
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    return NO;
}

写了一个demo,是经过简单的封装的,有兴趣的可以看看!
GitHub

相关文章

网友评论

  • skyz1126:多谢,正好用的上
  • PGOne爱吃饺子:哥们 你好,请问如何让他输入数字的时候不显示点,而是显示输入的数字
  • 菊上一枝梅:我突然想到,其实TextField根本不用加到view上,它只是用来控制输入内容的,所以我们初始化一个TextField就可以了了,直接用6个view显示小点就可以了,是不是
    菊上一枝梅:我实际测试了一下,TextField得加在view上才能弹出键盘,所以可以这样
    UITextField *textField = [[UITextField alloc] init];

    [self.view addSubview:textField];

    [textField becomeFirstResponder];
  • 天山雪莲_38324:有人做过微信支付管理修改支付密码模块的需求吗?
    First灬DKS:@天山雪莲_38324 我当时也是这种需求,我的做法是直接创建了三个密码输入框,输入完一个后,通过动画效果移除输入完的,移入没有输入的密码输入框!不知道还有没有好的方法
    天山雪莲_38324:@First灬DKS 是的。
    First灬DKS:你说的是:输入完一次密码之后,会从右边移出一个新的密码输入框这种需求吗?
  • 且随疾风0214:你试过6s上的情况吗,分割线显示的有问题,而且不是5个
    First灬DKS:@且随疾风0214 当线的宽度太小时,在有的手机上面由于分辨率的问题倒是显示不出来!
    且随疾风0214:@First灬DKS 宽度设为0.3的时候是有这种问题,为1的时候没有。
    First灬DKS:我试了,并没有发现这个问题
  • 天山雪莲_38324:666:+1: :+1: 博主给力啊。
  • 54bfe25edeb8:业界良心啊 完全没有多余的看不懂的 赞一个
    First灬DKS::smiley: 过奖了,喜欢就好!
  • 安静守护你:写的很不错 mark了 不过提出一个可以完善的地方: 应该禁止textField的粘贴复制功能,不然即便是输入的文字是白色的看不到 但是可以粘贴出来的
    First灬DKS:谢谢你的提议,我跟新一下文章;:smile:
  • 贱精先玍丶:赞一下👍. 我想问, 输入完毕之后, 如何再把所有移除,并且再判断接下来输入与上一次输入相同呢?
    First灬DKS:@贱精先玍丶 这个是清除输入框里面的文字的方法;
    贱精先玍丶:@First灬DKS 这个是在判断输入6个字符的时候调用吗?
    First灬DKS:我在代码里面又添加了清除的方法
    - (void)clearUpPassword
    {
    self.textField.text = @"";
    [self textFieldDidChange:self.textField];
    }
  • 夏夜晚风:666,简直太聪明了
    First灬DKS:谢谢!:smile:
  • 慌失失:写的太棒了,点个赞
    First灬DKS:@慌失失 :smiley:
  • iOS_tao:如果不是显示黑点,而是显示数字呢?
    First灬DKS:@iOS_tao 能不能把黑点变成UILabel,然后添加到数组里面,在键盘输入数字的时候,从数组中找到第几个label,然后赋值;
  • 戴仓薯:哈哈哈,不错的想法~
  • 这个汤圆没有馅:跟着敲了一遍,效果可以实现。谢谢博主。然后我这边有一个问题,就是分割线的宽度不一样,有些细有些粗,frame什么的都是跟博主一样的。
    菊上一枝梅:@TangyuanLiu 其实你把模拟器放到最大看效果应该是对的,有时模拟器缩小会造成显示误差
    这个汤圆没有馅:@First灬DKS 不好意思 好久没登简书。问题解决了呢,是模拟器的问题,在真机上运行就是好的
    First灬DKS:@汤了个圆 不好意思,这段时间不在,不知道你的问题解决了没?
  • Pusswzy:相当不错
    First灬DKS:@Pusswzy :smile:
  • 阿兹尔:能发个Demo链接
    First灬DKS:@阿兹尔 这是从项目中剥离出来的一部分,并没有写demo; :smiley:
  • 愚人船ios:赞一个!
    First灬DKS:@愚人船 谢谢! :smiley:

本文标题:iOS开发:仿微信、支付宝6位密码输入框

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