美文网首页详解demo
iOS Demo 详解(四) 密码输入框

iOS Demo 详解(四) 密码输入框

作者: 5a9c6f44e578 | 来源:发表于2017-03-06 17:26 被阅读160次

    效果图

    Paste_Image.png

    效果分析:
    整体是一个View 上面画了六个方框,用TextField输入,剩下密码模式和键盘的处理

    封装View.h 文件

    @interface TPPasswordTextView : UIView
    
    /**
     block  密码
     */
    @property (nonatomic, copy) void(^passwordDidChangeBlock)(NSString *password);
    
    
    /**
       密码框个数
     */
    @property (nonatomic, assign) NSInteger elementCount;
    
    
    /**
     设置元素的颜色,默认是黑色的颜色
     */
    @property (nonatomic, strong) UIColor *elementBorderColor;
    
    
    /**
       间距  默认是 4
     */
    @property (nonatomic, assign) CGFloat elementMargin;
    
    
    /**
       判断是否 隐藏键盘   默认是yes      yes 隐藏
     */
    @property (nonatomic, assign) BOOL autoHideKeyboard;
    
    
    /**
     边框 宽度 默认是1
     */
    @property (nonatomic, assign) CGFloat elementBorderWidth;
    
    
    /**
        清除所有密码
     */
    - (void)clearPassword;
    
    /**
      显示键盘
     */
    - (void)showKeyboard;
    
    
    /**
       隐藏键盘
     */
    - (void)hideKeyboard;
    
    
    @end
    

    .m

    @interface TPPasswordTextView ()
    
    // 主要作用是为了 展示 收齐 键盘
    @property(nonatomic, weak) UITextField *textField;
    
    //泛型约束   数组里面只能是  TextField
    @property (nonatomic, strong) NSMutableArray<UITextField *> *dataSource;
    
    @end
    
    @implementation TPPasswordTextView
    
    #pragma mark ==== 懒加载
    - (NSMutableArray *)dataSource {
        if (_dataSource == nil) {
            _dataSource = [NSMutableArray array];
        }
        return _dataSource;
    }
    
    
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            UITextField *textField = [[UITextField alloc] initWithFrame:self.bounds];
            
            textField.hidden = YES;
            
            // 数字键盘
            textField.keyboardType = UIKeyboardTypeNumberPad;
            // 添加  监听  TF 变化时执行
            [textField addTarget:self action:@selector(textChange:) forControlEvents:UIControlEventEditingChanged];
            
            [self addSubview:textField];
            
            self.textField = textField;
            
            //   隐藏  键盘
            self.autoHideKeyboard = YES;
        }
        return self;
    }
    
    
    
    //  set方法
    - (void)setElementCount:(NSInteger)elementCount {
        _elementCount = elementCount;
        if (elementCount <= 0) {
            return;
        }
        
        if (self.dataSource.count > 0) {
            
            //block 遍历  方法
            [self.dataSource enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                //单独取消一个
                [NSObject cancelPreviousPerformRequestsWithTarget:obj selector:@selector(removeFromSuperview) object:nil];
            
            }];
            
            // 类似于 for循环,但有效率高于for循环 makeObjectsPerformSelector:类似于NSNotifation机制,并发的执行同一件事,不能像for循环那样区别对待
         
            [self.dataSource makeObjectsPerformSelector:@selector(removeFromSuperview)];
            
            [self.dataSource removeAllObjects];
        }
        //  循环创建 TextField
        for (int i = 0; i < self.elementCount; i++)
        {
            UITextField *pwdTextField = [[UITextField alloc] init];
            
            pwdTextField.enabled = NO;
            
            pwdTextField.textAlignment = NSTextAlignmentCenter;//居中
            
            pwdTextField.secureTextEntry = YES;//设置密码模式
            //  不响应用户点击   仅做展示用    不挡住  self.textField 相应的事件
            pwdTextField.userInteractionEnabled = NO;
            
            // 插入一个pwdTextField ,并且在 self.textField 下面
            [self insertSubview:pwdTextField belowSubview:self.textField];
            
            [self.dataSource addObject:pwdTextField];
        }
    }
    
    
    
    
    - (void)setElementMargin:(CGFloat)elementMargin {
        _elementMargin = elementMargin;
    //    会默认调用layoutSubViews
        [self setNeedsLayout];
    //   自动调用drawRect方法
        [self setNeedsDisplay];
    }
    
    
    
    - (void)clearPassword {
        self.textField.text = nil;
        [self textChange:self.textField];
    }
    
    
    //  显示  键盘
    - (void)showKeyboard {
        [self.textField becomeFirstResponder];
    }
    
    
    //  回收键盘
    - (void)hideKeyboard {
        [self.textField resignFirstResponder];
    }
    
    
    #pragma mark - 文本框内容改变
    - (void)textChange:(UITextField *)textField {
        NSString *password = textField.text;
        if (password.length > self.elementCount) {
            return;
        }
        
        for (int i = 0; i < self.dataSource.count; i++)
        {
            UITextField *pwdTextField= [self.dataSource objectAtIndex:i];
            if (i < password.length) {
                NSString *pwd = [password substringWithRange:NSMakeRange(i, 1)];
                pwdTextField.text = pwd;
            } else {
                pwdTextField.text = nil;
            }
            
        }
        
        if (password.length == self.dataSource.count)
        {
            if (self.autoHideKeyboard) {
                [self hideKeyboard];//隐藏键盘
            }
        }
        
        !self.passwordDidChangeBlock ? : self.passwordDidChangeBlock(textField.text);
    }
    
    
    
    //子视图 重新布局
    - (void)layoutSubviews {
        [super layoutSubviews];
        CGFloat x = 0;
        CGFloat y = 0;
        CGFloat w = (self.bounds.size.width - (self.elementCount - 1) * self.elementMargin) / self.elementCount;
        CGFloat h = self.bounds.size.height;
        for (NSUInteger i = 0; i < self.dataSource.count; i++) {
            UITextField *pwdTextField = [self.dataSource objectAtIndex:i];
            
            //  x 起始点
            x = i * (w + self.elementMargin);
            pwdTextField.frame = CGRectMake(x, y, w, h);
        }
    }
    
    
    
    
    //  点击  弹出  键盘
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        [self showKeyboard];
    }
    
    
    
    //  绘图操作   画矩形
    - (void)drawRect:(CGRect)rect {
        [super drawRect:rect];
        
        //  获得处理的上下文
        CGContextRef context = UIGraphicsGetCurrentContext();
        
        [self.backgroundColor set];
        
        //   矩形
        CGContextFillRect(context, rect);
        
        //  设置线条样式
        CGContextSetLineCap(context, kCGLineCapSquare);
        
        // 设置 线条 粗细宽度
        CGContextSetLineWidth(context, self.elementBorderWidth);
        
        //  设置颜色
        CGContextSetStrokeColorWithColor(context, self.elementBorderColor.CGColor);
        
        //  设置当前填充颜色的图形上下文,使用CGColor
        CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
        
        CGContextBeginPath(context);
        if (self.elementMargin != 0) {
            for (UITextField *textField in self.dataSource) {
                CGRect rect = CGRectInset(textField.frame, self.elementBorderWidth, self.elementBorderWidth);
                CGFloat left = rect.origin.x;
                CGFloat right = rect.origin.x + rect.size.width;
                CGFloat top = rect.origin.y;
                CGFloat bottom = rect.origin.y + rect.size.height;
                
                //  开始画线   起始点
                CGContextMoveToPoint(context, left, top);
                //  顶部
                CGContextAddLineToPoint(context, right, top);
                // 右侧竖线
                CGContextAddLineToPoint(context, right, bottom);
                // 底部
                CGContextAddLineToPoint(context, left, bottom);
    //            封闭当前线路   连接起始点
                CGContextClosePath(context);
            }
        }
        else {
            CGPoint leftTopPoint, rightTopPoint, leftBottomPoint, rightBottomPoint;
            for (NSUInteger i = 0; i < self.dataSource.count; i++) {
                
                UITextField *textField = [self.dataSource objectAtIndex:i];
                
                CGRect rect = CGRectInset(textField.frame, self.elementBorderWidth, self.elementBorderWidth);
                
                CGFloat left = rect.origin.x;
                
                CGFloat right = rect.origin.x + rect.size.width;
                
                CGFloat top = rect.origin.y;
                
                CGFloat bottom = rect.origin.y + rect.size.height;
                
                //  开始画线
                CGContextMoveToPoint(context, left, top);
                // 画直线
                CGContextAddLineToPoint(context, left, bottom);
                
                CGContextClosePath(context);
                if (self.dataSource.count - 1 == i) {
                    CGContextMoveToPoint(context, right, top);
                    CGContextAddLineToPoint(context, right, bottom);
                    CGContextClosePath(context);
                    rightTopPoint = CGPointMake(right, top);
                    rightBottomPoint = CGPointMake(right, bottom);
                }else if (0 == i) {
                    leftTopPoint = CGPointMake(left, top);
                    leftBottomPoint = CGPointMake(left, bottom);
                }
            }
            
            CGContextMoveToPoint(context, leftTopPoint.x, leftTopPoint.y);
            CGContextAddLineToPoint(context, rightTopPoint.x, rightTopPoint.y);
            CGContextClosePath(context);
            
            CGContextMoveToPoint(context, leftBottomPoint.x, leftBottomPoint.y);
            CGContextAddLineToPoint(context, rightBottomPoint.x, rightBottomPoint.y);
            CGContextClosePath(context);
        }
        CGContextStrokePath(context);
    }
    
    
    @end
    
    

    </br>
    使用方式也很简单

    
        TPPasswordTextView *view4 = [[TPPasswordTextView alloc] initWithFrame:CGRectMake(30 , 140 , self.view.frame.size.width - 60 , 44)];
        
        //  背景色 方便  看
        view4.backgroundColor = [UIColor whiteColor];
        
        //  密码框个数
        view4.elementCount = 6;
        
        //  距离
        view4.elementMargin = 5;
        
        // 边框宽度
        view4.elementBorderWidth = 1;
        
        [self.view addSubview:view4];
        
        
        //实现block
        view4.passwordDidChangeBlock = ^(NSString *password){
            NSLog(@" 密码是 :  %@",password);
        };
    
    

    demo 地址:
    https://git.oschina.net/wwwzz/PassWordBoxDemo

    相关文章

      网友评论

        本文标题:iOS Demo 详解(四) 密码输入框

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