#import
#import "MZTTextField.h"
@interface PasswordView : UIView
//密码输入文本框
@property (nonatomic,strong) MZTTextField *passwordField;
@end
/**
设计思路:
第一步:先创建控件:标题、取消按钮、一个输入框。
第二步:再将输入框六等分,用分割线分开,这样看起来就有六个框了,再创建六个 密码点视图(就是黑圆点),位置根据输入框六等分来设置,添加到视图并全部hide,然后存放在一个数组里。
第三步:每次输入密码,先将全部密码点全部hide,然后再根据输入密码的长度,一个一个的显示出来,比如密码输入到第四位,就利用循环将数组前四位的密码点hide设置为NO。这样删除也好处理。
第四步:判断,显示动画。
**/
#import "PasswordView.h"
//禁止复制、粘贴、全选、剪切等操作的输入框
#import "MZTTextField.h"
//输入密码后的等待和成功动画
#import "PaymentLoadingHUD.h"
#import "PaymentSuccessHUD.h"
#import
#define ScreenWidth [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height
//密码位数
static NSInteger const DotsNumber = 6;
//密码点的宽和高 应该是等高等宽的正方形 方便设置为圆角
static CGFloat const DotWith_height = 12;
@interface PasswordView ()
//标题
@property (nonatomic,strong) UILabel *title;
//取消按钮
@property (nonatomic,strong) UIButton *btn_cancel;
//忘记密码按钮
@property (nonatomic,strong) UIButton *forgetPassword;
//分割线
@property (nonatomic,strong) UIView *line;
//用来装密码点的数组,里面装的是view
@property (nonatomic,strong) NSMutableArray *passwordDotsArray;
//用户的默认支付密码
@property (nonatomic,strong) NSString *password;
@property (nonatomic,strong) UILabel *PaymentText;
@end
@implementation PasswordView
#pragma mark - 初始化密码、视图、数组
//重写初始化类方法
-(instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor whiteColor];
[self getPassword];
//创建子控件,并添加到视图
[self InitAllUI];
}
return self;
}
////获取支付密码
-(void)getPassword {
self.password = @"131415";
}
-(void)InitAllUI {
//标题
self.title = [[UILabel alloc]init];
self.title.text = @"请输入支付密码";
self.title.textAlignment = NSTextAlignmentCenter;
self.title.font = [UIFont systemFontOfSize:16];
CGSize size = [self.title.text sizeWithAttributes:@{NSFontAttributeName:self.title.font}];
[self addSubview:self.title];
[self.title mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.mas_top).with.offset(15);
make.centerX.equalTo(self.mas_centerX);
make.size.mas_equalTo(CGSizeMake(size.width+10, size.height));
}];
//取消按钮
self.btn_cancel = [UIButton buttonWithType:UIButtonTypeCustom];
[self.btn_cancel setImage:[UIImage imageNamed:@"箭头灰"] forState:UIControlStateNormal];
[self.btn_cancel addTarget:self action:@selector(TakeUpPassword) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.btn_cancel];
[self.btn_cancel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.title.mas_centerY);
make.left.equalTo(self.mas_left).with.offset(10);
make.size.mas_equalTo(CGSizeMake(28, 28));
}];
//分割线
self.line = [UIView new];
self.line.backgroundColor = [UIColor colorWithRed:222/255.0f green:222/255.0f blue:222/255.0f alpha:1];
[self addSubview:self.line];
[self.line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.title.mas_bottom).with.offset(15);
make.left.equalTo(self.mas_left);
make.size.mas_equalTo(CGSizeMake(MZT_SCREEN_WIDTH, 1));
}];
//密码输入框
self.passwordField = [[MZTTextField alloc]init];
self.passwordField.backgroundColor = [UIColor whiteColor];
self.passwordField.alpha = 0.8;
self.passwordField.textColor = [UIColor clearColor];//这两个颜色一定要是clearColor,不然删除到第一个时可能会看见输入的数字
self.passwordField.tintColor = [UIColor clearColor];
self.passwordField.layer.borderColor = [UIColor colorWithRed:222/255.0f green:222/255.0f blue:222/255.0f alpha:1].CGColor;
self.passwordField.layer.borderWidth = 1;
self.passwordField.layer.cornerRadius = 8.0;
self.passwordField.keyboardType = UIKeyboardTypeNumberPad;
self.passwordField.secureTextEntry = YES;
[self.passwordField addTarget:self action:@selector(passwordFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
self.passwordField.delegate = self;
[self.passwordField becomeFirstResponder];
[self addSubview:self.passwordField];
//忘记密码
self.forgetPassword = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[self.forgetPassword setTitle:@"忘记密码?" forState:UIControlStateNormal];
self.forgetPassword.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
[self.forgetPassword addTarget:self action:@selector(ForgetPassword) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.forgetPassword];
}
-(void) layoutSubviews {
[super layoutSubviews];
self.passwordField.frame = CGRectMake((ScreenWidth-ScreenWidth*0.15*6)/2, 70, ScreenWidth*0.15*6, ScreenWidth*0.15);
[self.forgetPassword mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.passwordField.mas_right);
make.top.equalTo(self.passwordField.mas_bottom).with.offset(10);
make.size.mas_equalTo(CGSizeMake(80, 16));
}];
//密码点要根据 passwordField.frame 来设置
[self initDotsViews];
}
-(void) initDotsViews {
//初始化数组
self.passwordDotsArray = [NSMutableArray arrayWithCapacity:DotsNumber];
CGFloat password_width = self.passwordField.frame.size.width/DotsNumber;
CGFloat password_height = self.passwordField.frame.size.height;
for (int i = 0; i < DotsNumber; i++) {
//分割线
UIView *line = [[UIView alloc] initWithFrame:CGRectMake(i * password_width, 0, 1, password_height)];
line.backgroundColor = [UIColor colorWithRed:222/255.0f green:222/255.0f blue:222/255.0f alpha:1];
//不要第一个分割线
if(i!=0) {
[self.passwordField addSubview:line];
}
//密码点x和y坐标
CGFloat dotViewX = (i + 1)*password_width - password_width / 2.0 - DotWith_height / 2.0;
CGFloat dotViewY = (password_height - DotWith_height) / 2.0;
//密码点视图
UIView *dotView = [[UIView alloc] initWithFrame:CGRectMake(dotViewX, dotViewY, DotWith_height, DotWith_height)];
dotView.backgroundColor = [UIColor colorWithRed:30/255.0f green:30/255.0f blue:30/255.0f alpha:1];
dotView.layer.cornerRadius = DotWith_height/2.0;
//创建好之后先隐藏
dotView.hidden = YES;
[self.passwordField addSubview:dotView];
[self.passwordDotsArray addObject:dotView];
}
}
#pragma mark - 点击事件
-(void) TakeUpPassword {
//收起视图
[self.passwordField resignFirstResponder];
//并清除密码
[self cleanPassword];
[UIView animateWithDuration:0.3 animations:^{
self.frame = CGRectMake(ScreenWidth, ScreenHeight*0.34, ScreenWidth, ScreenHeight*0.66);
}];
}
-(void) ForgetPassword {
MZTLog(@"忘记密码");
}
#pragma mark - 判断密码
-(void)passwordFieldDidChange:(UITextField *)textField {
//先隐藏全部密码点
[self setDotsViewHidden];
//再根据输入框的长度来设置显示的相应个数的密码点视图
for (int i = 0; i < self.passwordField.text.length; i ++)
{
if (self.passwordDotsArray.count > i )
{
//取出密码点视图并显示
UIView *dotView = self.passwordDotsArray[i];
[dotView setHidden:NO];
}
}
//当输入六位密码
if (self.passwordField.text.length == 6)
{
//判断输入密码与用户密码相等
if ([self.passwordField.text isEqualToString:self.password])
{
NSLog(@" 打印信息 密码正确");
[textField resignFirstResponder];
//显示等待付款动画
[PaymentLoadingHUD showIn:self];
self.PaymentText = [[UILabel alloc]init];
self.PaymentText.text = @"正在付款...";
self.PaymentText.font = [UIFont systemFontOfSize:14];
CGSize size = [self.PaymentText.text sizeWithAttributes:@{NSFontAttributeName:self.PaymentText.font}];
[self addSubview:self.PaymentText];
[self.PaymentText mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.mas_centerX).with.offset(10);
make.centerY.equalTo(self.mas_centerY).with.offset(50);
make.size.mas_equalTo(CGSizeMake(size.width+10, size.width));
}];
//显示付款成功动画
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(PaymentSuccess) userInfo:nil repeats:NO];
}
else
{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@""
message:@"支付密码不正确"
delegate:self
cancelButtonTitle:@"重新输入"
otherButtonTitles:@"忘记密码", nil];
[alert show];
}
}
}
-(void) cleanPassword {
////清除密码
self.passwordField.text = @"";//置空输入框
[self setDotsViewHidden];//隐藏所有密码点视图
}
-(void) setDotsViewHidden {
////隐藏所有密码点
for (UIView *view in self.passwordDotsArray) {
[view setHidden:YES];
}
}
-(void) PaymentSuccess {
[PaymentLoadingHUD hideIn:self];
[PaymentSuccessHUD showIn:self];
self.PaymentText.text = @"付款成功";
}
#pragma mark - UITextFieldDelegate
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// >= 六位数不能再输入
if (self.passwordField.text.length >= DotsNumber) {
return NO;
}
return YES;
}
#pragma mark - UIAlertViewDelegate
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString* buttonTitle = [alertView buttonTitleAtIndex:buttonIndex];
if ([buttonTitle isEqualToString:@"重新输入"]) {
[self cleanPassword];
}
else if ([buttonTitle isEqualToString:@"忘记密码"]) {
NSLog(@"忘记密码,重新设置密码");
}
}
@end
#import
@interface MZTTextField : UITextField
@end
#import "MZTTextField.h"
@implementation MZTTextField
////禁止输入框的复制、粘贴、全选、剪切等操作
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender {
UIMenuController *MenuController = [UIMenuController sharedMenuController];
if (MenuController) {
[UIMenuController sharedMenuController].menuVisible = NO;
}
return NO;
}
@end
#import
@interface PaymentLoadingHUD : UIView
-(void)start;
-(void)hide;
+(PaymentLoadingHUD*)showIn:(UIView*)view;
+(PaymentLoadingHUD*)hideIn:(UIView*)view;
@end
#import "PaymentLoadingHUD.h"
#define BlueColor [UIColor colorWithRed:28/255.0 green:138/255.0 blue:234/255.0 alpha:1]
static CGFloat lineWidth = 5.0f;
@implementation PaymentLoadingHUD
{
CADisplayLink *link;
CAShapeLayer *animationLayer;
CGFloat startAngle;
CGFloat endAngle;
CGFloat progress;
}
-(instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
[self buildUI];
}
return self;
}
-(void) buildUI {
animationLayer = [CAShapeLayer layer];
animationLayer.bounds = CGRectMake(0, 0, 60, 60);
animationLayer.position = CGPointMake(self.bounds.size.width/2.0f, self.bounds.size.height/2.0);
animationLayer.fillColor = [UIColor clearColor].CGColor;
animationLayer.strokeColor = BlueColor.CGColor;
animationLayer.lineWidth = lineWidth;
animationLayer.lineCap = kCALineCapRound;
[self.layer addSublayer:animationLayer];
link = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkAction)];
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
link.paused = true;
}
-(void)displayLinkAction {
progress += [self speed];
if (progress >= 1) {
progress = 0;
}
[self updateAnimationLayer];
}
-(void)updateAnimationLayer{
startAngle = -M_PI_2;
endAngle = -M_PI_2 +progress * M_PI * 2;
if (endAngle > M_PI) {
CGFloat progress1 = 1 - (1 - progress)/0.25;
startAngle = -M_PI_2 + progress1 * M_PI * 2;
}
CGFloat radius = animationLayer.bounds.size.width/2.0f - lineWidth/2.0f;
CGFloat centerX = animationLayer.bounds.size.width/2.0f;
CGFloat centerY = animationLayer.bounds.size.height/2.0f;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(centerX, centerY) radius:radius startAngle:startAngle endAngle:endAngle clockwise:true];
path.lineCapStyle = kCGLineCapRound;
animationLayer.path = path.CGPath;
}
-(CGFloat)speed{
if (endAngle > M_PI) {
return 0.3/60.0f;
}
return 2/60.0f;
}
+(PaymentLoadingHUD *)showIn:(UIView*)view {
[self hideIn:view];
PaymentLoadingHUD *hud = [[PaymentLoadingHUD alloc] initWithFrame:view.bounds];
[hud start];
[view addSubview:hud];
return hud;
}
+(PaymentLoadingHUD *)hideIn:(UIView *)view {
PaymentLoadingHUD *hud = nil;
for (PaymentLoadingHUD *subView in view.subviews) {
if ([subView isKindOfClass:[PaymentLoadingHUD class]]) {
[subView hide];
[subView removeFromSuperview];
hud = subView;
}
}
return hud;
}
-(void)start {
link.paused = false;
}
-(void)hide {
link.paused = true;
progress = 0;
}
@end
#import
@interface PaymentSuccessHUD : UIView
-(void)start;
-(void)hide;
+(PaymentSuccessHUD*)showIn:(UIView*)view;
+(PaymentSuccessHUD*)hideIn:(UIView*)view;
@end
#import "PaymentSuccessHUD.h"
static CGFloat lineWidth = 4.0f;
static CGFloat circleDuriation = 0.5f;
static CGFloat checkDuration = 0.2f;
#define BlueColor [UIColor colorWithRed:28/255.0 green:138/255.0 blue:234/255.0 alpha:1]
@implementation PaymentSuccessHUD
{
CALayer *_animationLayer;
}
//显示
+ (PaymentSuccessHUD*)showIn:(UIView*)view {
[self hideIn:view];
PaymentSuccessHUD *hud = [[PaymentSuccessHUD alloc] initWithFrame:view.bounds];
[hud start];
[view addSubview:hud];
return hud;
}
//隐藏
+ (PaymentSuccessHUD *)hideIn:(UIView *)view {
PaymentSuccessHUD *hud = nil;
for (PaymentSuccessHUD *subView in view.subviews) {
if ([subView isKindOfClass:[PaymentSuccessHUD class]]) {
[subView hide];
[subView removeFromSuperview];
hud = subView;
}
}
return hud;
}
- (void)start {
[self circleAnimation];
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 0.8 * circleDuriation * NSEC_PER_SEC);
dispatch_after(time, dispatch_get_main_queue(), ^(void){
[self checkAnimation];
});
}
- (void)hide {
for (CALayer *layer in _animationLayer.sublayers) {
[layer removeAllAnimations];
}
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self buildUI];
}
return self;
}
- (void)buildUI {
_animationLayer = [CALayer layer];
_animationLayer.bounds = CGRectMake(0, 0, 60, 60);
_animationLayer.position = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
[self.layer addSublayer:_animationLayer];
}
//画圆
- (void)circleAnimation {
CAShapeLayer *circleLayer = [CAShapeLayer layer];
circleLayer.frame = _animationLayer.bounds;
[_animationLayer addSublayer:circleLayer];
circleLayer.fillColor = [[UIColor clearColor] CGColor];
circleLayer.strokeColor = BlueColor.CGColor;
circleLayer.lineWidth = lineWidth;
circleLayer.lineCap = kCALineCapRound;
CGFloat lineWidth = 5.0f;
CGFloat radius = _animationLayer.bounds.size.width/2.0f - lineWidth/2.0f;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:circleLayer.position radius:radius startAngle:-M_PI/2 endAngle:M_PI*3/2 clockwise:true];
circleLayer.path = path.CGPath;
CABasicAnimation *circleAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
circleAnimation.duration = circleDuriation;
circleAnimation.fromValue = @(0.0f);
circleAnimation.toValue = @(1.0f);
circleAnimation.delegate = self;
[circleAnimation setValue:@"circleAnimation" forKey:@"animationName"];
[circleLayer addAnimation:circleAnimation forKey:nil];
}
//对号
- (void)checkAnimation {
CGFloat a = _animationLayer.bounds.size.width;
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(a*2.7/10,a*5.4/10)];
[path addLineToPoint:CGPointMake(a*4.5/10,a*7/10)];
[path addLineToPoint:CGPointMake(a*7.8/10,a*3.8/10)];
CAShapeLayer *checkLayer = [CAShapeLayer layer];
checkLayer.path = path.CGPath;
checkLayer.fillColor = [UIColor clearColor].CGColor;
checkLayer.strokeColor = BlueColor.CGColor;
checkLayer.lineWidth = lineWidth;
checkLayer.lineCap = kCALineCapRound;
checkLayer.lineJoin = kCALineJoinRound;
[_animationLayer addSublayer:checkLayer];
CABasicAnimation *checkAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
checkAnimation.duration = checkDuration;
checkAnimation.fromValue = @(0.0f);
checkAnimation.toValue = @(1.0f);
checkAnimation.delegate = self;
[checkAnimation setValue:@"checkAnimation" forKey:@"animationName"];
[checkLayer addAnimation:checkAnimation forKey:nil];
}
@end
个人转载。以防丢失
iOS-支付密码插件_SunSatan的博客-CSDN博客_ios 支付密码控件