iOSUI工具

iOS 密码输入框

2020-07-21  本文已影响0人  _Waiting_

我们在输入验证码或者密码的时候,有的UI往往会设计成如下格式,颇是令人头疼。好看是好看但是不好写,吐槽完毕。

效果图

本方法的设计思路
利用UITextField+UILabel的模式进行组合设计。
UITextField负责接收输入的数据。
UILabel负责显示数据。

代码
.h

#import <UIKit/UIKit.h>

typedef  void(^HanTextFieldBlock)(NSString * _Nullable codeString);

NS_ASSUME_NONNULL_BEGIN

@interface HanTextField : UIView
@property(nonatomic, assign)NSInteger itemNumber;
@property(nonatomic, assign)BOOL isSecure;
@property(nonatomic, strong)UIFont *textFont;
@property(nonatomic, strong)UIColor *textColor;
@property(nonatomic, strong)UIColor *lineColor;
//输入指定位数字符后的回调
@property(nonatomic, copy)HanTextFieldBlock block;

@end

@interface HanHideMenuTextField:UITextField

@end

NS_ASSUME_NONNULL_END

.m

#import "HanTextField.h"

@interface HanTextField ()<UITextFieldDelegate>

@property(nonatomic, strong) HanHideMenuTextField *textField;
@property(nonatomic, strong) NSMutableArray *labArr;
@property(nonatomic, strong) NSMutableArray *lineArr;
@property(nonatomic, copy) NSString *codeString;

@end

@implementation HanTextField

-(instancetype)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        self.isSecure = NO;
        self.itemNumber = 6;
        self.textColor = [UIColor whiteColor];
        self.textFont = [UIFont systemFontOfSize:16];
    }
    return self;
}

-(void)createSubViews{
    
    self.textField.hidden = NO;
    [self.labArr removeAllObjects];
    
    CGFloat h = self.frame.size.height;
    CGFloat w = self.frame.size.width;
    CGFloat iw = w/self.itemNumber;

    for (int i = 0; i < self.itemNumber ; i++) {

        UILabel *lab = [[UILabel alloc] init];
        lab.frame = CGRectMake(iw * i, 0, iw, h);
        lab.textAlignment = NSTextAlignmentCenter;
        lab.textColor = self.textColor;
        lab.font = self.textFont;
        [self addSubview:lab];
        [self.labArr addObject:lab];
    }
    [self createLineView];
    
}
-(void)createLineView{
    CGFloat h = self.frame.size.height;
    CGFloat w = self.frame.size.width;
    CGFloat iw = w/self.itemNumber;

    [self.lineArr removeAllObjects];
    for (int i = 0; i < self.itemNumber ; i++) {

        UIView *view = [[UIView alloc] init];
        view.bounds = CGRectMake(0, 0, iw * 0.7, 1);
        view.center = CGPointMake(iw * (0.5 + i) , h - 0.5);
        view.backgroundColor = [UIColor whiteColor];
        [self addSubview:view];
        [self.lineArr addObject:view];
    }
    
}
- (void)textDidChanged:(UITextField *)textField {
    
    if (textField.text.length <= self.itemNumber){
        NSInteger index = textField.text.length - 1;
        if (self.codeString.length < textField.text.length) {
            UILabel *label = self.labArr[index];
            label.text = [textField.text substringFromIndex:index];
            if (self.isSecure) {
                label.text = @"*";
            }
        }else{
            UILabel *label = self.labArr[index + 1];
            label.text = @"";
        }
        if (textField.text.length == self.itemNumber) {
            if (self.block) {
                self.block(textField.text);
            }
        }
    }else{
        textField.text = [textField.text substringToIndex:self.itemNumber];
    }
    
    
    self.codeString = textField.text;
}
#pragma mark - 设置仅可输入数字
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    return [self validateNumber:string];
}

- (BOOL)validateNumber:(NSString*)number {
    BOOL res = YES;
    NSCharacterSet* tmpSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
    int i = 0;
    while (i < number.length) {
        NSString * string = [number substringWithRange:NSMakeRange(i, 1)];
        NSRange range = [string rangeOfCharacterFromSet:tmpSet];
        if (range.length == 0) {
            res = NO;
            break;
        }
        i++;
    }
    return res;
}
#pragma mark - setter
- (void)setItemNumber:(NSInteger)itemNumber{
    _itemNumber = itemNumber;
    for (UIView *vi in self.subviews) {
        [vi removeFromSuperview];
    }
    self.textField = nil;
    [self createSubViews];
}

- (void)setTextFont:(UIFont *)textFont{
    for (UILabel *lab in self.labArr) {
        lab.font = textFont;
    }
    _textFont = textFont;
}

- (void)setTextColor:(UIColor *)textColor{
    for (UILabel *lab in self.labArr) {
        lab.textColor = textColor;
    }
    _textColor = textColor;
}
-(void)setLineColor:(UIColor *)lineColor{
    for (UIView *view in self.lineArr) {
        view.backgroundColor = lineColor;
    }
    _lineColor = lineColor;
}
#pragma mark - getter
-(UITextField *)textField{
    if (_textField == nil) {
        _textField = [[HanHideMenuTextField alloc] init];
        _textField.frame = self.bounds;
        _textField.delegate = self;
        _textField.backgroundColor = [UIColor clearColor];
        _textField.textColor = [UIColor clearColor];
        _textField.tintColor = [UIColor clearColor];
        [_textField addTarget:self action:@selector(textDidChanged:) forControlEvents:UIControlEventEditingChanged];
        [self addSubview:self.textField];
    }
    return _textField;
}

-(NSMutableArray *)labArr{
    if (_labArr == nil) {
        _labArr = [NSMutableArray array];
    }
    return _labArr;
}

-(NSMutableArray *)lineArr{
    if (_lineArr == nil) {
        _lineArr = [NSMutableArray array];
    }
    return _lineArr;
}
@end

@implementation HanHideMenuTextField
#pragma mark - 设置TextField 不可复制 粘贴
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    [[UIMenuController sharedMenuController] hideMenu];
    if (action == @selector(copy:)) {
        return NO;
    } else if (action == @selector(selectAll:)) {
        return NO;
    }
    
    return NO;
}
@end

动画效果

    -(void)animation{
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        animation.fromValue = [NSNumber numberWithFloat:1.0f];
        animation.toValue = [NSNumber numberWithFloat:0.0f];//这是透明度。
        animation.autoreverses = YES;
        animation.duration = 1;
        animation.repeatCount = MAXFLOAT;
        animation.removedOnCompletion = NO;
        animation.fillMode = kCAFillModeForwards;
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
        [self. textField.layer addAnimation:animation forKey:nil];
    }

用法

HanTextField *textField = [[HanTextField alloc] initWithFrame:CGRectMake(0, 100, [UIScreen mainScreen].bounds.size.width, 40)];
textField.itemNumber = 4;
textField.textColor = [UIColor redColor];
textField.lineColor = [UIColor redColor];
textField.textFont = [UIFont systemFontOfSize:20];
textField.isSecure = YES;
[self.view addSubview:textField];

textField.block = ^(NSString * _Nullable codeString) {
        NSLog(@"--->%@",codeString);
};

写了格式校验,现在只能输入数字,如果想要别的格式校验 请更改这个方法 shouldChangeCharactersInRange 中的 校验方式

上一篇下一篇

猜你喜欢

热点阅读