iOS-仿京东6位密码支付输入框

开发需求中有时候我们需要用于安全支付的功能, 需要设置APP钱包的支付密码, 页面是仿照京东的6位输入框的的做法, 效果如下图:

47775A92-2454-45D6-8C69-054AFB968B94.png

看起来是有由6个UITextField组成, 其实并不是,这只是一个假象.

一、实现思路:

  • 1. 创建一个UITextField,仅仅一个而不是六个! 然后用5根竖线进行分割,这样我们看到的就是一个有6个等同输入框的视图.

  • 2. 创建黑点可以通过创建一个正方形的UIView,设置圆角为宽高的一半,就是一个圆了,使其 frame 显示在中间则黑点居中即可.

  • 3. 当点击输入时候使用shouldChangeCharactersInRange 方法来用来输入的 textfield 做处理, 是否成为第一响应者,用来用户输入, 监听其值的改变.

  • 4. 当密码的长度达到需要的长度时,关闭第一响应者. 这里可以使用 block 来传递 password 的值.

  • 5. 提供一个清除 password 的方法

二、程序实现

先抽出加密支付页面 ZLSafetyPswView, 在.m中主要就是实现页面的效果:

1
2
3
4
5
6
7
8
#define kDotSize CGSizeMake (10, 10) // 密码点的大小
#define kDotCount 6  // 密码个数
#define K_Field_Height self.frame.size.height  // 每一个输入框的高度等于当前view的高度
@interface ZLSafetyPswView () <UITextFieldDelegate>
// 密码输入文本框
@property (nonatomic, strong) UITextField *pswTextField;
// 用于存放加密黑色点
@property (nonatomic, strong) NSMutableArray *dotArr;

创建分割线和黑点.

1
2
3
4
5
6
7
#pragma mark - 懒加载
- (NSMutableArray *)dotArr {
     if  (!_dotArr) {
         _dotArr = [NSMutableArray array];
     }
     return  _dotArr;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- ( void )setupWithPswTextField {
     
     // 每个密码输入框的宽度
     CGFloat width = self.frame.size.width / kDotCount;
     
     // 生成分割线
     for  ( int  i = 0; i < kDotCount - 1; i++) {
         UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMinX(self.pswTextField.frame) + (i + 1) * width, 0, 1, K_Field_Height)];
         lineView.backgroundColor = [UIColor grayColor];
         [self addSubview:lineView];
     }
     
     self.dotArr = [[NSMutableArray alloc] init];
     
     // 生成中间的黑点
     for  ( int  i = 0; i < kDotCount; i++) {
         UIView *dotView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMinX(self.pswTextField.frame) + (width - kDotCount) / 2 + i * width, CGRectGetMinY(self.pswTextField.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 addSubview:dotView];
         
         // 把创建的黑色点加入到存放数组中
         [self.dotArr addObject:dotView];
     }
}

创建一个UITextField.切记输入的文字颜色和输入框光标的颜色为透明!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#pragma mark - init
- (UITextField *)pswTextField {
     
     if  (!_pswTextField) {
         _pswTextField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, K_Field_Height)];
         _pswTextField.backgroundColor = [UIColor clearColor];
         // 输入的文字颜色为无色
         _pswTextField.textColor = [UIColor clearColor];
         // 输入框光标的颜色为无色
         _pswTextField.tintColor = [UIColor clearColor];
         _pswTextField.delegate = self;
         _pswTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;
         _pswTextField.keyboardType = UIKeyboardTypeNumberPad;
         _pswTextField.layer.borderColor = [[UIColor grayColor] CGColor];
         _pswTextField.layer.borderWidth = 1;
         [_pswTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
         [self addSubview:_pswTextField];
     }
     return  _pswTextField;
}

文本框内容改变时,用来用户输入, 监听其值的改变.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#pragma mark - 文本框内容改变
/**
  *  重置显示的点
  */
- ( void )textFieldDidChange:(UITextField *)textField {
     
     NSLog(@ "目前输入显示----%@" , textField.text);
     
     for  (UIView *dotView in self.dotArr) {
         dotView.hidden = YES;
     }
     for  ( int  i = 0; i < textField.text.length; i++) {
         ((UIView *)[self.dotArr objectAtIndex:i]).hidden = NO;
     }
     if  (textField.text.length == kDotCount) { 
         NSLog(@ "---输入完毕---" );
         
         [self.pswTextField resignFirstResponder];
     }
     
     // 获取用户输入密码
     !self.passwordDidChangeBlock ? : self.passwordDidChangeBlock(textField.text);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- ( 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;
     }
}

清除密码时收起键盘并将文本输入框值置为空.

1
2
3
4
5
6
7
8
9
#pragma mark - publick method
/**
  *  清除密码
  */
- ( void )clearUpPassword {
     [self.pswTextField resignFirstResponder];
     self.pswTextField.text = nil;
     [self textFieldDidChange:self.pswTextField];
}

 

接着在当前所需控制器里,创建支付页面并拿到用户输入密码去做支付相关逻辑处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 加密支付页面
     ZLSafetyPswView *pswView = [[ZLSafetyPswView alloc] initWithFrame:CGRectMake(50, 100, self.view.frame.size.width - 100, 45)];
     [self.view addSubview:pswView];
     self.pswView = pswView;
     pswView.passwordDidChangeBlock = ^(NSString *password) {
         NSLog(@ "---用户输入密码为: %@" ,password);
     };
     
     UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
     button.backgroundColor = [UIColor orangeColor];
     button.frame = CGRectMake(100, 280, self.view.frame.size.width - 200, 50);
     [button addTarget:self action:@selector(clearPsw) forControlEvents:UIControlEventTouchUpInside];
     [button setTitle:@ "清空密码"  forState:UIControlStateNormal];
     [self.view addSubview:button];

方便测试加上清空密码按钮

1
2
3
4
5
6
7
8
// 清空密码
- ( void )clearPsw {
     
     [self.pswView clearUpPassword];
}
- ( void )touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
     [self.view endEditing:YES];
}
三、运行效果与文件截图

1、运行效果:

2、文件截图:

3.jpg

四、其他补充

我这里是做6位支付密码的, 你同样可以修改kDotCount密码个数值,目前也有4位的.

 

界面性问题可以根据自己项目需求调整即可, 具体可参考代码, 项目能够直接运行!

如需看详情版,请点击这里下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值