1
This commit is contained in:
31
keyBoard/Class/Vender/CRBoxInputView/CRBoxFlowLayout.h
Normal file
31
keyBoard/Class/Vender/CRBoxInputView/CRBoxFlowLayout.h
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// CRBoxFlowLayout.h
|
||||
// CaiShenYe
|
||||
//
|
||||
// Created by Chobits on 2019/1/3.
|
||||
// Copyright © 2019 Chobits. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CRBoxFlowLayout : UICollectionViewFlowLayout
|
||||
|
||||
/** ifNeedEqualGap
|
||||
* default: YES
|
||||
*/
|
||||
@property (assign, nonatomic) BOOL ifNeedEqualGap;
|
||||
|
||||
@property (assign, nonatomic) NSInteger itemNum;
|
||||
|
||||
/** minLineSpacing
|
||||
* default: 10
|
||||
*/
|
||||
@property (assign, nonatomic) NSInteger minLineSpacing;
|
||||
|
||||
- (void)autoCalucateLineSpacing;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
58
keyBoard/Class/Vender/CRBoxInputView/CRBoxFlowLayout.m
Normal file
58
keyBoard/Class/Vender/CRBoxInputView/CRBoxFlowLayout.m
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// CRBoxFlowLayout.m
|
||||
// CaiShenYe
|
||||
//
|
||||
// Created by Chobits on 2019/1/3.
|
||||
// Copyright © 2019 Chobits. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CRBoxFlowLayout.h"
|
||||
|
||||
@implementation CRBoxFlowLayout
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
[self initPara];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)initPara
|
||||
{
|
||||
self.ifNeedEqualGap = YES;
|
||||
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
|
||||
self.minLineSpacing = 10;
|
||||
self.minimumLineSpacing = 0;
|
||||
self.minimumInteritemSpacing = 0;
|
||||
self.sectionInset = UIEdgeInsetsZero;
|
||||
self.itemNum = 1;
|
||||
}
|
||||
|
||||
- (void)prepareLayout
|
||||
{
|
||||
if (_ifNeedEqualGap) {
|
||||
[self autoCalucateLineSpacing];
|
||||
}
|
||||
|
||||
[super prepareLayout];
|
||||
}
|
||||
|
||||
- (void)autoCalucateLineSpacing
|
||||
{
|
||||
if (self.itemNum > 1) {
|
||||
CGFloat width = CGRectGetWidth(self.collectionView.frame);
|
||||
self.minimumLineSpacing = floor(1.0 * (width - self.itemNum * self.itemSize.width - self.collectionView.contentInset.left - self.collectionView.contentInset.right) / (self.itemNum - 1));
|
||||
|
||||
if (self.minimumLineSpacing < self.minLineSpacing) {
|
||||
self.minimumLineSpacing = self.minLineSpacing;
|
||||
}
|
||||
}else{
|
||||
self.minimumLineSpacing = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
38
keyBoard/Class/Vender/CRBoxInputView/CRBoxInputCell.h
Normal file
38
keyBoard/Class/Vender/CRBoxInputView/CRBoxInputCell.h
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// CRBoxInputCell.h
|
||||
// CaiShenYe
|
||||
//
|
||||
// Created by Chobits on 2019/1/3.
|
||||
// Copyright © 2019 Chobits. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "CRBoxInputCellProperty.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#define CRBoxCursoryAnimationKey @"CRBoxCursoryAnimationKey"
|
||||
#define CRBoxInputCellID @"CRBoxInputCellID"
|
||||
|
||||
@interface CRBoxInputCell : UICollectionViewCell
|
||||
|
||||
/**
|
||||
cursor
|
||||
You should not use these properties, unless you know what you are doing.
|
||||
*/
|
||||
@property (strong, nonatomic) UIView *cursorView;
|
||||
@property (assign, nonatomic) BOOL ifNeedCursor;
|
||||
|
||||
/**
|
||||
boxInputCellProperty
|
||||
You should not use these properties, unless you know what you are doing.
|
||||
*/
|
||||
@property (strong, nonatomic) CRBoxInputCellProperty *boxInputCellProperty;
|
||||
|
||||
// 你可以在继承的子类中重写父类方法
|
||||
// You can inherit and rewrite
|
||||
- (UIView *)createCustomSecurityView __deprecated_msg("Please use `customSecurityViewBlock` in CRBoxInputCellProperty.");
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
281
keyBoard/Class/Vender/CRBoxInputView/CRBoxInputCell.m
Normal file
281
keyBoard/Class/Vender/CRBoxInputView/CRBoxInputCell.m
Normal file
@@ -0,0 +1,281 @@
|
||||
//
|
||||
// CRBoxInputCell.m
|
||||
// CaiShenYe
|
||||
//
|
||||
// Created by Chobits on 2019/1/3.
|
||||
// Copyright © 2019 Chobits. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CRBoxInputCell.h"
|
||||
#import <Masonry/Masonry.h>
|
||||
#import "CRLineView.h"
|
||||
|
||||
@interface CRBoxInputCell ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@property (strong, nonatomic) UILabel *valueLabel;
|
||||
@property (strong, nonatomic) CABasicAnimation *opacityAnimation;
|
||||
@property (strong, nonatomic) UIView *customSecurityView;
|
||||
|
||||
@property (strong, nonatomic) CRLineView *lineView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation CRBoxInputCell
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
|
||||
if (self) {
|
||||
[self createUIBase];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)initPara
|
||||
{
|
||||
self.ifNeedCursor = YES;
|
||||
self.userInteractionEnabled = NO;
|
||||
}
|
||||
|
||||
- (void)createUIBase
|
||||
{
|
||||
[self initPara];
|
||||
|
||||
_valueLabel = [UILabel new];
|
||||
_valueLabel.font = [UIFont systemFontOfSize:38];
|
||||
[self.contentView addSubview:_valueLabel];
|
||||
[_valueLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.offset(0);
|
||||
make.centerY.offset(0);
|
||||
}];
|
||||
|
||||
_cursorView = [UIView new];
|
||||
[self.contentView addSubview:_cursorView];
|
||||
[_cursorView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.offset(0);
|
||||
make.centerY.offset(0);
|
||||
}];
|
||||
|
||||
[self initCellProperty];
|
||||
}
|
||||
|
||||
- (void)initCellProperty
|
||||
{
|
||||
CRBoxInputCellProperty *cellProperty = [CRBoxInputCellProperty new];
|
||||
self.boxInputCellProperty = cellProperty;
|
||||
}
|
||||
|
||||
- (void)valueLabelLoadData
|
||||
{
|
||||
_valueLabel.hidden = NO;
|
||||
[self hideCustomSecurityView];
|
||||
|
||||
// 默认字体配置
|
||||
__weak typeof(self) weakSelf = self;
|
||||
void (^defaultTextConfig)(void) = ^{
|
||||
if (weakSelf.boxInputCellProperty.cellFont) {
|
||||
weakSelf.valueLabel.font = weakSelf.boxInputCellProperty.cellFont;
|
||||
}
|
||||
|
||||
if (weakSelf.boxInputCellProperty.cellTextColor) {
|
||||
weakSelf.valueLabel.textColor = weakSelf.boxInputCellProperty.cellTextColor;
|
||||
}
|
||||
};
|
||||
|
||||
// 占位字符字体配置
|
||||
void (^placeholderTextConfig)(void) = ^{
|
||||
if (weakSelf.boxInputCellProperty.cellFont) {
|
||||
weakSelf.valueLabel.font = weakSelf.boxInputCellProperty.cellPlaceholderFont;
|
||||
}
|
||||
|
||||
if (weakSelf.boxInputCellProperty.cellTextColor) {
|
||||
weakSelf.valueLabel.textColor = weakSelf.boxInputCellProperty.cellPlaceholderTextColor;
|
||||
}
|
||||
};
|
||||
|
||||
BOOL hasOriginValue = self.boxInputCellProperty.originValue && self.boxInputCellProperty.originValue.length > 0;
|
||||
if (hasOriginValue) {
|
||||
if (self.boxInputCellProperty.ifShowSecurity) {
|
||||
if (self.boxInputCellProperty.securityType == CRBoxSecuritySymbolType) {
|
||||
_valueLabel.text = self.boxInputCellProperty.securitySymbol;
|
||||
}else if (self.boxInputCellProperty.securityType == CRBoxSecurityCustomViewType) {
|
||||
_valueLabel.hidden = YES;
|
||||
[self showCustomSecurityView];
|
||||
}
|
||||
|
||||
}else{
|
||||
_valueLabel.text = self.boxInputCellProperty.originValue;
|
||||
}
|
||||
defaultTextConfig();
|
||||
}else{
|
||||
BOOL hasPlaceholderText = self.boxInputCellProperty.cellPlaceholderText && self.boxInputCellProperty.cellPlaceholderText.length > 0;
|
||||
// 有占位字符
|
||||
if (hasPlaceholderText) {
|
||||
_valueLabel.text = self.boxInputCellProperty.cellPlaceholderText;
|
||||
placeholderTextConfig();
|
||||
}
|
||||
// 空
|
||||
else{
|
||||
_valueLabel.text = @"";
|
||||
defaultTextConfig();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Custom security view
|
||||
- (void)showCustomSecurityView
|
||||
{
|
||||
if (!self.customSecurityView.superview) {
|
||||
[self.contentView addSubview:self.customSecurityView];
|
||||
[self.customSecurityView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.mas_equalTo(UIEdgeInsetsZero);
|
||||
}];
|
||||
}
|
||||
|
||||
self.customSecurityView.alpha = 1;
|
||||
}
|
||||
|
||||
- (void)hideCustomSecurityView
|
||||
{
|
||||
// Must add this judge. Otherwise _customSecurityView maybe null, and cause error.
|
||||
if (_customSecurityView) {
|
||||
self.customSecurityView.alpha = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Setter & Getter
|
||||
- (CABasicAnimation *)opacityAnimation
|
||||
{
|
||||
if (!_opacityAnimation) {
|
||||
_opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
|
||||
_opacityAnimation.fromValue = @(1.0);
|
||||
_opacityAnimation.toValue = @(0.0);
|
||||
_opacityAnimation.duration = 0.9;
|
||||
_opacityAnimation.repeatCount = HUGE_VALF;
|
||||
_opacityAnimation.removedOnCompletion = YES;
|
||||
_opacityAnimation.fillMode = kCAFillModeForwards;
|
||||
_opacityAnimation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
|
||||
}
|
||||
|
||||
return _opacityAnimation;
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected
|
||||
{
|
||||
if (selected) {
|
||||
self.layer.borderColor = self.boxInputCellProperty.cellBorderColorSelected.CGColor;
|
||||
self.backgroundColor = self.boxInputCellProperty.cellBgColorSelected;
|
||||
}else{
|
||||
BOOL hasFill = _valueLabel.text.length > 0 ? YES : NO;
|
||||
UIColor *cellBorderColor = self.boxInputCellProperty.cellBorderColorNormal;
|
||||
UIColor *cellBackgroundColor = self.boxInputCellProperty.cellBgColorNormal;
|
||||
if (hasFill) {
|
||||
if (self.boxInputCellProperty.cellBorderColorFilled) {
|
||||
cellBorderColor = self.boxInputCellProperty.cellBorderColorFilled;
|
||||
}
|
||||
if (self.boxInputCellProperty.cellBgColorFilled) {
|
||||
cellBackgroundColor = self.boxInputCellProperty.cellBgColorFilled;
|
||||
}
|
||||
}
|
||||
self.layer.borderColor = cellBorderColor.CGColor;
|
||||
self.backgroundColor = cellBackgroundColor;
|
||||
}
|
||||
|
||||
if (_lineView) {
|
||||
// 未选中
|
||||
if (!selected) {
|
||||
if (self.boxInputCellProperty.originValue.length > 0 && _lineView.underlineColorFilled) {
|
||||
// 有内容
|
||||
_lineView.lineView.backgroundColor = _lineView.underlineColorFilled;
|
||||
}else if (_lineView.underlineColorNormal) {
|
||||
// 无内容
|
||||
_lineView.lineView.backgroundColor = _lineView.underlineColorNormal;
|
||||
}else{
|
||||
// 默认
|
||||
_lineView.lineView.backgroundColor = CRColorMaster;
|
||||
}
|
||||
}
|
||||
// 已选中
|
||||
else if (selected && _lineView.underlineColorSelected){
|
||||
_lineView.lineView.backgroundColor = _lineView.underlineColorSelected;
|
||||
}
|
||||
// 默认
|
||||
else{
|
||||
_lineView.lineView.backgroundColor = CRColorMaster;
|
||||
}
|
||||
|
||||
_lineView.selected = selected;
|
||||
}
|
||||
|
||||
if (_ifNeedCursor) {
|
||||
if (selected) {
|
||||
_cursorView.hidden= NO;
|
||||
[_cursorView.layer addAnimation:self.opacityAnimation forKey:CRBoxCursoryAnimationKey];
|
||||
}else{
|
||||
_cursorView.hidden= YES;
|
||||
[_cursorView.layer removeAnimationForKey:CRBoxCursoryAnimationKey];
|
||||
}
|
||||
}else{
|
||||
_cursorView.hidden= YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setBoxInputCellProperty:(CRBoxInputCellProperty *)boxInputCellProperty
|
||||
{
|
||||
_boxInputCellProperty = boxInputCellProperty;
|
||||
|
||||
_cursorView.backgroundColor = boxInputCellProperty.cellCursorColor;
|
||||
[_cursorView mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.mas_equalTo(boxInputCellProperty.cellCursorWidth);
|
||||
make.height.mas_equalTo(boxInputCellProperty.cellCursorHeight);
|
||||
}];
|
||||
self.layer.cornerRadius = boxInputCellProperty.cornerRadius;
|
||||
self.layer.borderWidth = boxInputCellProperty.borderWidth;
|
||||
|
||||
[self valueLabelLoadData];
|
||||
}
|
||||
|
||||
- (UIView *)customSecurityView
|
||||
{
|
||||
if (!_customSecurityView) {
|
||||
// Compatiable for 0.19 verion and earlier.
|
||||
if ([self respondsToSelector:@selector(createCustomSecurityView)]) {
|
||||
_customSecurityView = [self createCustomSecurityView];
|
||||
}
|
||||
else if(_boxInputCellProperty.customSecurityViewBlock){
|
||||
NSAssert(_boxInputCellProperty.customSecurityViewBlock, @"customSecurityViewBlock can not be null!");
|
||||
_customSecurityView = _boxInputCellProperty.customSecurityViewBlock();
|
||||
}
|
||||
}
|
||||
|
||||
return _customSecurityView;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
if (_boxInputCellProperty.showLine && !_lineView) {
|
||||
NSAssert(_boxInputCellProperty.customLineViewBlock, @"customLineViewBlock can not be null!");
|
||||
_lineView = _boxInputCellProperty.customLineViewBlock();
|
||||
[self.contentView addSubview:_lineView];
|
||||
[_lineView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.right.bottom.top.offset(0);
|
||||
}];
|
||||
}
|
||||
|
||||
if (_boxInputCellProperty.configCellShadowBlock) {
|
||||
_boxInputCellProperty.configCellShadowBlock(weakSelf.layer);
|
||||
}
|
||||
|
||||
[super layoutSubviews];
|
||||
}
|
||||
|
||||
@end
|
||||
200
keyBoard/Class/Vender/CRBoxInputView/CRBoxInputCellProperty.h
Normal file
200
keyBoard/Class/Vender/CRBoxInputView/CRBoxInputCellProperty.h
Normal file
@@ -0,0 +1,200 @@
|
||||
//
|
||||
// CRBoxInputCellProperty.h
|
||||
// CaiShenYe
|
||||
//
|
||||
// Created by Chobits on 2019/1/3.
|
||||
// Copyright © 2019 Chobits. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "CRLineView.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSInteger, CRBoxSecurityType) {
|
||||
CRBoxSecuritySymbolType,
|
||||
CRBoxSecurityCustomViewType,
|
||||
};
|
||||
|
||||
typedef UIView *_Nonnull(^CustomSecurityViewBlock)(void);
|
||||
typedef CRLineView *_Nonnull(^CustomLineViewBlock)(void);
|
||||
typedef void(^ConfigCellShadowBlock)(CALayer *layer);
|
||||
|
||||
@interface CRBoxInputCellProperty : NSObject <NSCopying>
|
||||
|
||||
#pragma mark - UI
|
||||
/**
|
||||
cell边框宽度
|
||||
默认:0.5
|
||||
*/
|
||||
@property (assign, nonatomic) CGFloat borderWidth;
|
||||
|
||||
/**
|
||||
cell边框颜色
|
||||
状态:未选中状态时
|
||||
默认:[UIColor colorWithRed:228/255.0 green:228/255.0 blue:228/255.0 alpha:1]
|
||||
*/
|
||||
@property (copy, nonatomic) UIColor *cellBorderColorNormal;
|
||||
|
||||
/**
|
||||
cell边框颜色
|
||||
状态:选中状态时
|
||||
默认:[UIColor colorWithRed:255/255.0 green:70/255.0 blue:62/255.0 alpha:1]
|
||||
*/
|
||||
@property (copy, nonatomic) UIColor *cellBorderColorSelected;
|
||||
|
||||
/**
|
||||
cell边框颜色
|
||||
状态:填充文字后,未选中状态时
|
||||
默认:nil
|
||||
*/
|
||||
@property (copy, nonatomic) UIColor *__nullable cellBorderColorFilled;
|
||||
|
||||
/**
|
||||
cell背景颜色
|
||||
状态:无填充文字,未选中状态时
|
||||
默认:[UIColor whiteColor]
|
||||
*/
|
||||
@property (copy, nonatomic) UIColor *cellBgColorNormal;
|
||||
|
||||
/**
|
||||
cell背景颜色
|
||||
状态:选中状态时
|
||||
默认:[UIColor whiteColor]
|
||||
*/
|
||||
@property (copy, nonatomic) UIColor *cellBgColorSelected;
|
||||
|
||||
/**
|
||||
cell背景颜色
|
||||
状态:填充文字后,未选中状态时
|
||||
默认:与cellBgColorFilled相同
|
||||
*/
|
||||
@property (copy, nonatomic) UIColor *__nullable cellBgColorFilled;
|
||||
|
||||
|
||||
/**
|
||||
光标颜色
|
||||
默认: [UIColor colorWithRed:255/255.0 green:70/255.0 blue:62/255.0 alpha:1]
|
||||
*/
|
||||
@property (copy, nonatomic) UIColor *cellCursorColor;
|
||||
|
||||
/**
|
||||
光标宽度
|
||||
默认: 2
|
||||
*/
|
||||
@property (assign, nonatomic) CGFloat cellCursorWidth;
|
||||
|
||||
/**
|
||||
光标高度
|
||||
默认: 32
|
||||
*/
|
||||
@property (assign, nonatomic) CGFloat cellCursorHeight;
|
||||
|
||||
/**
|
||||
圆角
|
||||
默认: 4
|
||||
*/
|
||||
@property (assign, nonatomic) CGFloat cornerRadius;
|
||||
|
||||
|
||||
|
||||
#pragma mark - line
|
||||
/**
|
||||
显示下划线
|
||||
默认: NO
|
||||
*/
|
||||
@property (assign, nonatomic) BOOL showLine;
|
||||
|
||||
|
||||
|
||||
#pragma mark - label
|
||||
/**
|
||||
字体/字号
|
||||
默认:[UIFont systemFontOfSize:20];
|
||||
*/
|
||||
@property (copy, nonatomic) UIFont *cellFont;
|
||||
|
||||
/**
|
||||
字体颜色
|
||||
默认:[UIColor blackColor];
|
||||
*/
|
||||
@property (copy, nonatomic) UIColor *cellTextColor;
|
||||
|
||||
|
||||
|
||||
#pragma mark - Security
|
||||
/**
|
||||
是否密文显示
|
||||
默认:NO
|
||||
*/
|
||||
@property (assign, nonatomic) BOOL ifShowSecurity;
|
||||
|
||||
/**
|
||||
密文符号
|
||||
默认:✱
|
||||
说明:只有ifShowSecurity=YES时,有效
|
||||
*/
|
||||
@property (copy, nonatomic) NSString *securitySymbol;
|
||||
|
||||
/**
|
||||
保存当前显示的字符
|
||||
若想一次性修改所有输入值,请使用 CRBoxInputView中的'reloadInputString'方法
|
||||
禁止修改该值!!!(除非你知道该怎么使用它。)
|
||||
*/
|
||||
@property (copy, nonatomic, readonly) NSString *originValue;
|
||||
- (void)setMyOriginValue:(NSString *)originValue;
|
||||
|
||||
/**
|
||||
密文类型
|
||||
默认:CRBoxSecuritySymbolType
|
||||
类型说明:
|
||||
CRBoxSecuritySymbolType 符号类型,根据securitySymbol,originValue的内容来显示
|
||||
CRBoxSecurityCustomViewType 自定义View类型,可以自定义密文状态下的图片,View
|
||||
*/
|
||||
@property (assign, nonatomic) CRBoxSecurityType securityType;
|
||||
|
||||
|
||||
|
||||
#pragma mark - Placeholder
|
||||
/**
|
||||
占位符默认填充值
|
||||
禁止修改该值!!!(除非你知道该怎么使用它。)
|
||||
*/
|
||||
@property (strong, nonatomic) NSString *__nullable cellPlaceholderText;
|
||||
|
||||
/**
|
||||
占位符字体颜色
|
||||
默认:[UIColor colorWithRed:114/255.0 green:126/255.0 blue:124/255.0 alpha:0.3];
|
||||
*/
|
||||
@property (copy, nonatomic) UIColor *cellPlaceholderTextColor;
|
||||
|
||||
/**
|
||||
占位符字体/字号
|
||||
默认:[UIFont systemFontOfSize:20];
|
||||
*/
|
||||
@property (copy, nonatomic) UIFont *cellPlaceholderFont;
|
||||
|
||||
|
||||
|
||||
#pragma mark - Block
|
||||
/**
|
||||
自定义密文View回调
|
||||
*/
|
||||
@property (copy, nonatomic) CustomSecurityViewBlock customSecurityViewBlock;
|
||||
/**
|
||||
自定义下划线回调
|
||||
*/
|
||||
@property (copy, nonatomic) CustomLineViewBlock customLineViewBlock;
|
||||
/**
|
||||
自定义阴影回调
|
||||
*/
|
||||
@property (copy, nonatomic) ConfigCellShadowBlock __nullable configCellShadowBlock;
|
||||
|
||||
|
||||
|
||||
#pragma mark - Test
|
||||
@property (assign, nonatomic) NSInteger index;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
157
keyBoard/Class/Vender/CRBoxInputView/CRBoxInputCellProperty.m
Normal file
157
keyBoard/Class/Vender/CRBoxInputView/CRBoxInputCellProperty.m
Normal file
@@ -0,0 +1,157 @@
|
||||
//
|
||||
// CRBoxInputself.m
|
||||
// CaiShenYe
|
||||
//
|
||||
// Created by Chobits on 2019/1/3.
|
||||
// Copyright © 2019 Chobits. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CRBoxInputCellProperty.h"
|
||||
#import <Masonry/Masonry.h>
|
||||
|
||||
@interface CRBoxInputCellProperty ()
|
||||
|
||||
@property (copy, nonatomic, readwrite) NSString *originValue;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation CRBoxInputCellProperty
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
// UI
|
||||
self.borderWidth = (0.5);
|
||||
self.cellBorderColorNormal = [UIColor colorWithRed:228/255.0 green:228/255.0 blue:228/255.0 alpha:1];
|
||||
self.cellBorderColorSelected = [UIColor colorWithRed:255/255.0 green:70/255.0 blue:62/255.0 alpha:1];
|
||||
self.cellBorderColorFilled = nil;
|
||||
self.cellBgColorNormal = [UIColor whiteColor];
|
||||
self.cellBgColorSelected = [UIColor whiteColor];
|
||||
self.cellBgColorFilled = nil;
|
||||
self.cellCursorColor = [UIColor colorWithRed:255/255.0 green:70/255.0 blue:62/255.0 alpha:1];
|
||||
self.cellCursorWidth = 2;
|
||||
self.cellCursorHeight = 32;
|
||||
self.cornerRadius = 4;
|
||||
|
||||
// line
|
||||
self.showLine = NO;
|
||||
|
||||
// label
|
||||
self.cellFont = [UIFont systemFontOfSize:20];
|
||||
self.cellTextColor = [UIColor blackColor];
|
||||
|
||||
// Security
|
||||
self.ifShowSecurity = NO;
|
||||
self.securitySymbol = @"✱";
|
||||
self.originValue = @"";
|
||||
self.securityType = CRBoxSecuritySymbolType;
|
||||
|
||||
// Placeholder
|
||||
self.cellPlaceholderText = nil;
|
||||
self.cellPlaceholderTextColor = [UIColor colorWithRed:114/255.0 green:116/255.0 blue:124/255.0 alpha:0.3];
|
||||
self.cellPlaceholderFont = [UIFont systemFontOfSize:20];
|
||||
|
||||
// Block
|
||||
self.customSecurityViewBlock = ^UIView * _Nonnull{
|
||||
return [weakSelf defaultCustomSecurityView];
|
||||
};
|
||||
self.customLineViewBlock = ^CRLineView * _Nonnull{
|
||||
return [CRLineView new];
|
||||
};
|
||||
self.configCellShadowBlock = nil;
|
||||
|
||||
// Test
|
||||
self.index = 0;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Copy
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
CRBoxInputCellProperty *copy = [[self class] allocWithZone:zone];
|
||||
|
||||
// UI
|
||||
copy.borderWidth = _borderWidth;
|
||||
copy.cellBorderColorNormal = [_cellBorderColorNormal copy];
|
||||
copy.cellBorderColorSelected = [_cellBorderColorSelected copy];
|
||||
if (_cellBorderColorFilled) {
|
||||
copy.cellBorderColorFilled = [_cellBorderColorFilled copy];
|
||||
}
|
||||
copy.cellBgColorNormal = [_cellBgColorNormal copy];
|
||||
copy.cellBgColorSelected = [_cellBgColorSelected copy];
|
||||
if (_cellBgColorFilled) {
|
||||
copy.cellBgColorFilled = [_cellBgColorFilled copy];
|
||||
}
|
||||
copy.cellCursorColor = [_cellCursorColor copy];
|
||||
copy.cellCursorWidth = _cellCursorWidth;
|
||||
copy.cellCursorHeight = _cellCursorHeight;
|
||||
copy.cornerRadius = _cornerRadius;
|
||||
|
||||
// line
|
||||
copy.showLine = _showLine;
|
||||
|
||||
// label
|
||||
copy.cellFont = [_cellFont copy];
|
||||
copy.cellTextColor = [_cellTextColor copy];
|
||||
|
||||
// Security
|
||||
copy.ifShowSecurity = _ifShowSecurity;
|
||||
copy.securitySymbol = [_securitySymbol copy];
|
||||
copy.originValue = [_originValue copy];
|
||||
copy.securityType = _securityType;
|
||||
|
||||
// Placeholder
|
||||
if (_cellPlaceholderText) {
|
||||
copy.cellPlaceholderText = [_cellPlaceholderText copy];
|
||||
}
|
||||
copy.cellPlaceholderTextColor = [_cellPlaceholderTextColor copy];
|
||||
copy.cellPlaceholderFont = [_cellPlaceholderFont copy];
|
||||
|
||||
// Block
|
||||
copy.customSecurityViewBlock = [_customSecurityViewBlock copy];
|
||||
copy.customLineViewBlock = [_customLineViewBlock copy];
|
||||
if (_configCellShadowBlock) {
|
||||
copy.configCellShadowBlock = [_configCellShadowBlock copy];
|
||||
}
|
||||
|
||||
// Test
|
||||
copy.index = _index;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
#pragma mark - Getter
|
||||
- (UIView *)defaultCustomSecurityView
|
||||
{
|
||||
UIView *customSecurityView = [UIView new];
|
||||
customSecurityView.backgroundColor = [UIColor clearColor];
|
||||
|
||||
// circleView
|
||||
static CGFloat circleViewWidth = 20;
|
||||
UIView *circleView = [UIView new];
|
||||
circleView.backgroundColor = [UIColor blackColor];
|
||||
circleView.layer.cornerRadius = 4;
|
||||
[customSecurityView addSubview:circleView];
|
||||
[circleView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.height.mas_equalTo(circleViewWidth);
|
||||
make.centerX.offset(0);
|
||||
make.centerY.offset(0);
|
||||
}];
|
||||
|
||||
return customSecurityView;
|
||||
}
|
||||
|
||||
#pragma mark - Setter
|
||||
- (void)setMyOriginValue:(NSString *)originValue {
|
||||
_originValue = originValue;
|
||||
}
|
||||
|
||||
@end
|
||||
165
keyBoard/Class/Vender/CRBoxInputView/CRBoxInputView.h
Executable file
165
keyBoard/Class/Vender/CRBoxInputView/CRBoxInputView.h
Executable file
@@ -0,0 +1,165 @@
|
||||
//
|
||||
// CRBoxInputView.h
|
||||
// CRBoxInputView
|
||||
//
|
||||
// Created by Chobits on 2019/1/3.
|
||||
// Copyright © 2019 Chobits. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "CRBoxFlowLayout.h"
|
||||
#import "CRBoxInputCellProperty.h"
|
||||
#import "CRBoxInputCell.h"
|
||||
@class CRBoxInputView;
|
||||
|
||||
typedef NS_ENUM(NSInteger, CRTextEditStatus) {
|
||||
CRTextEditStatus_Idle,
|
||||
CRTextEditStatus_BeginEdit,
|
||||
CRTextEditStatus_EndEdit,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, CRInputType) {
|
||||
/// 数字
|
||||
CRInputType_Number,
|
||||
/// 普通(不作任何处理)
|
||||
CRInputType_Normal,
|
||||
/// 自定义正则(此时需要设置customInputRegex)
|
||||
CRInputType_Regex,
|
||||
};
|
||||
|
||||
typedef void(^TextDidChangeblock)(NSString * _Nullable text, BOOL isFinished);
|
||||
typedef void(^TextEditStatusChangeblock)(CRTextEditStatus editStatus);
|
||||
typedef NSString *(^TextCustomProcessblock)(NSString * _Nullable text);
|
||||
|
||||
@interface CRBoxInputView : UIView
|
||||
|
||||
/**
|
||||
是否需要光标
|
||||
ifNeedCursor
|
||||
default: YES
|
||||
*/
|
||||
@property (assign, nonatomic) BOOL ifNeedCursor;
|
||||
|
||||
/**
|
||||
验证码长度
|
||||
codeLength
|
||||
default: 4
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) NSInteger codeLength; //If you want to set codeLength, please use `- (instancetype)initWithCodeLength:(NSInteger)codeLength, or - (void)resetCodeLength:(NSInteger)codeLength beginEdit:(BOOL)beginEdit` in CRBoxInputView.
|
||||
|
||||
/**
|
||||
是否开启密文模式
|
||||
描述:你可以在任何时候修改该属性,并且已经存在的文字会自动刷新。
|
||||
ifNeedSecurity
|
||||
desc: You can change this property anytime. And the existing texts can be refreshed automatically.
|
||||
default: NO
|
||||
*/
|
||||
@property (assign, nonatomic) BOOL ifNeedSecurity;
|
||||
|
||||
/**
|
||||
显示密文的延时时间
|
||||
securityDelay
|
||||
desc: show security delay time
|
||||
default: 0.3
|
||||
*/
|
||||
@property (assign, nonatomic) CGFloat securityDelay;
|
||||
|
||||
/**
|
||||
键盘类型
|
||||
keyBoardType
|
||||
default: UIKeyboardTypeNumberPad
|
||||
*/
|
||||
@property (assign, nonatomic) UIKeyboardType keyBoardType;
|
||||
|
||||
/**
|
||||
输入样式
|
||||
inputType
|
||||
default: CRInputType_Number
|
||||
*/
|
||||
@property (assign, nonatomic) CRInputType inputType;
|
||||
|
||||
/**
|
||||
自定义正则匹配输入内容
|
||||
customInputRegex
|
||||
default: @""
|
||||
当inputType == CRInputType_Regex时才会生效
|
||||
*/
|
||||
@property (copy, nonatomic) NSString * _Nullable customInputRegex;
|
||||
|
||||
/**
|
||||
textContentType
|
||||
描述: 你可以设置为 'nil' 或者 'UITextContentTypeOneTimeCode' 来自动获取短信验证码
|
||||
desc: You set this 'nil' or 'UITextContentTypeOneTimeCode' to auto fill verify code.
|
||||
default: nil
|
||||
*/
|
||||
@property (null_unspecified,nonatomic,copy) UITextContentType textContentType NS_AVAILABLE_IOS(10_0);
|
||||
|
||||
/**
|
||||
占位字符填充值
|
||||
说明:在对应的输入框没有内容时,会显示该值。
|
||||
默认:nil
|
||||
*/
|
||||
@property (strong, nonatomic) NSString * _Nullable placeholderText;
|
||||
|
||||
/**
|
||||
弹出键盘时,是否清空所有输入
|
||||
只有在输入的字数等于codeLength时,生效
|
||||
default: NO
|
||||
*/
|
||||
@property (assign, nonatomic) BOOL ifClearAllInBeginEditing;
|
||||
|
||||
|
||||
@property (copy, nonatomic) TextDidChangeblock _Nullable textDidChangeblock;
|
||||
@property (copy, nonatomic) TextEditStatusChangeblock _Nullable textEditStatusChangeblock;
|
||||
/// 文本自定义处理
|
||||
@property (copy, nonatomic) TextCustomProcessblock _Nullable textCustomProcessblock;
|
||||
@property (strong, nonatomic) CRBoxFlowLayout * _Nullable boxFlowLayout;
|
||||
@property (strong, nonatomic) CRBoxInputCellProperty * _Nullable customCellProperty;
|
||||
@property (strong, nonatomic, readonly) NSString * _Nullable textValue;
|
||||
@property (strong, nonatomic) UIView * _Nullable inputAccessoryView;
|
||||
|
||||
/**
|
||||
装载数据和准备界面
|
||||
desc: Load and prepareView
|
||||
beginEdit: 自动开启编辑模式
|
||||
default: YES
|
||||
*/
|
||||
- (void)loadAndPrepareView;
|
||||
- (void)loadAndPrepareViewWithBeginEdit:(BOOL)beginEdit;
|
||||
|
||||
/**
|
||||
重载输入的数据(用来设置预设数据)
|
||||
desc:Reload string. (You can use this function to set deault value)
|
||||
*/
|
||||
- (void)reloadInputString:(NSString *_Nullable)value;
|
||||
|
||||
/**
|
||||
清空输入
|
||||
desc: Clear all
|
||||
beginEdit: 自动开启编辑模式
|
||||
default: YES
|
||||
*/
|
||||
- (void)clearAll;
|
||||
- (void)clearAllWithBeginEdit:(BOOL)beginEdit;
|
||||
|
||||
- (UICollectionView *_Nullable)mainCollectionView;
|
||||
|
||||
// 快速设置
|
||||
// Qiuck set
|
||||
- (void)quickSetSecuritySymbol:(NSString *_Nullable)securitySymbol;
|
||||
|
||||
// 你可以在继承的子类中调用父类方法
|
||||
// You can inherit and call super
|
||||
- (void)initDefaultValue;
|
||||
|
||||
// 你可以在继承的子类中重写父类方法
|
||||
// You can inherit and rewrite
|
||||
- (UICollectionViewCell *_Nullable)customCollectionView:(UICollectionView *_Nullable)collectionView cellForItemAtIndexPath:(NSIndexPath *_Nullable)indexPath;
|
||||
|
||||
// code Length 调整
|
||||
- (void)resetCodeLength:(NSInteger)codeLength beginEdit:(BOOL)beginEdit;
|
||||
|
||||
// Init
|
||||
- (instancetype _Nullable )initWithCodeLength:(NSInteger)codeLength;
|
||||
|
||||
@end
|
||||
649
keyBoard/Class/Vender/CRBoxInputView/CRBoxInputView.m
Executable file
649
keyBoard/Class/Vender/CRBoxInputView/CRBoxInputView.m
Executable file
@@ -0,0 +1,649 @@
|
||||
//
|
||||
// CRBoxInputView.m
|
||||
// CRBoxInputView
|
||||
//
|
||||
// Created by Chobits on 2019/1/3.
|
||||
// Copyright © 2019 Chobits. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CRBoxInputView.h"
|
||||
#import <Masonry/Masonry.h>
|
||||
#import "CRBoxTextView.h"
|
||||
|
||||
typedef NS_ENUM(NSInteger, CRBoxTextChangeType) {
|
||||
CRBoxTextChangeType_NoChange,
|
||||
CRBoxTextChangeType_Insert,
|
||||
CRBoxTextChangeType_Delete,
|
||||
};
|
||||
|
||||
@interface CRBoxInputView () <UICollectionViewDataSource, UICollectionViewDelegate, UITextFieldDelegate>
|
||||
{
|
||||
NSInteger _oldLength;
|
||||
BOOL _ifNeedBeginEdit;
|
||||
}
|
||||
|
||||
@property (nonatomic, assign) NSInteger codeLength;
|
||||
@property (nonatomic, strong) UITapGestureRecognizer *tapGR;
|
||||
@property (nonatomic, strong) CRBoxTextView *textView;
|
||||
@property (nonatomic, strong) UICollectionView *mainCollectionView;
|
||||
@property (nonatomic, strong) NSMutableArray <NSString *> *valueArr;
|
||||
@property (nonatomic, strong) NSMutableArray <CRBoxInputCellProperty *> *cellPropertyArr;
|
||||
|
||||
@end
|
||||
|
||||
@implementation CRBoxInputView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self initDefaultValue];
|
||||
[self addNotificationObserver];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)coder
|
||||
{
|
||||
self = [super initWithCoder:coder];
|
||||
if (self) {
|
||||
[self initDefaultValue];
|
||||
[self addNotificationObserver];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self initDefaultValue];
|
||||
[self addNotificationObserver];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype _Nullable )initWithCodeLength:(NSInteger)codeLength
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self initDefaultValue];
|
||||
[self addNotificationObserver];
|
||||
self.codeLength = codeLength;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self removeNotificationObserver];
|
||||
}
|
||||
|
||||
#pragma mark - Notification Observer
|
||||
- (void)addNotificationObserver
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)removeNotificationObserver {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(NSNotification *)notification
|
||||
{
|
||||
// 触发home按下,光标动画移除
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(NSNotification *)notification
|
||||
{
|
||||
// 重新进来后响应,光标动画重新开始
|
||||
[self reloadAllCell];
|
||||
}
|
||||
|
||||
#pragma mark - You can inherit
|
||||
- (void)initDefaultValue
|
||||
{
|
||||
_oldLength = 0;
|
||||
self.ifNeedSecurity = NO;
|
||||
self.securityDelay = 0.3;
|
||||
self.codeLength = 4;
|
||||
self.ifNeedCursor = YES;
|
||||
self.keyBoardType = UIKeyboardTypeNumberPad;
|
||||
self.inputType = CRInputType_Number;
|
||||
self.customInputRegex = @"";
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
_valueArr = [NSMutableArray new];
|
||||
_ifNeedBeginEdit = NO;
|
||||
}
|
||||
|
||||
#pragma mark - LoadAndPrepareView
|
||||
- (void)loadAndPrepareView
|
||||
{
|
||||
[self loadAndPrepareViewWithBeginEdit:YES];
|
||||
}
|
||||
|
||||
- (void)loadAndPrepareViewWithBeginEdit:(BOOL)beginEdit
|
||||
{
|
||||
if (_codeLength<=0) {
|
||||
NSAssert(NO, @"请输入大于0的验证码位数");
|
||||
return;
|
||||
}
|
||||
|
||||
[self generateCellPropertyArr];
|
||||
|
||||
// mainCollectionView
|
||||
if (!self.mainCollectionView || ![self.subviews containsObject:self.mainCollectionView]) {
|
||||
[self addSubview:self.mainCollectionView];
|
||||
[self.mainCollectionView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.mas_equalTo(UIEdgeInsetsZero);
|
||||
}];
|
||||
}
|
||||
|
||||
// textView
|
||||
if (!self.textView || ![self.subviews containsObject:self.textView]) {
|
||||
[self addSubview:self.textView];
|
||||
[self.textView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.height.mas_equalTo(0);
|
||||
make.left.top.mas_equalTo(0);
|
||||
}];
|
||||
}
|
||||
|
||||
// tap
|
||||
if (self.tapGR.view != self) {
|
||||
[self addGestureRecognizer:self.tapGR];
|
||||
}
|
||||
|
||||
if (![self.textView.text isEqualToString:self.customCellProperty.originValue]) {
|
||||
self.textView.text = self.customCellProperty.originValue;
|
||||
[self textDidChange:self.textView];
|
||||
}
|
||||
|
||||
if (beginEdit) {
|
||||
[self beginEdit];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)generateCellPropertyArr
|
||||
{
|
||||
[self.cellPropertyArr removeAllObjects];
|
||||
for (int i = 0; i < self.codeLength; i++) {
|
||||
[self.cellPropertyArr addObject:[self.customCellProperty copy]];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - code Length 调整
|
||||
- (void)resetCodeLength:(NSInteger)codeLength beginEdit:(BOOL)beginEdit
|
||||
{
|
||||
if (codeLength<=0) {
|
||||
NSAssert(NO, @"请输入大于0的验证码位数");
|
||||
return;
|
||||
}
|
||||
|
||||
self.codeLength = codeLength;
|
||||
[self generateCellPropertyArr];
|
||||
[self clearAllWithBeginEdit:beginEdit];
|
||||
}
|
||||
|
||||
#pragma mark - Reload Input View
|
||||
- (void)reloadInputString:(NSString *_Nullable)value
|
||||
{
|
||||
if (![self.textView.text isEqualToString:value]) {
|
||||
self.textView.text = value;
|
||||
[self baseTextDidChange:self.textView manualInvoke:YES];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - UITextFieldDelegate
|
||||
- (void)textFieldDidBeginEditing:(UITextField *)textField
|
||||
{
|
||||
_ifNeedBeginEdit = YES;
|
||||
|
||||
if (self.ifClearAllInBeginEditing && self.textValue.length == self.codeLength) {
|
||||
[self clearAll];
|
||||
}
|
||||
|
||||
if (self.textEditStatusChangeblock) {
|
||||
self.textEditStatusChangeblock(CRTextEditStatus_BeginEdit);
|
||||
}
|
||||
|
||||
[self reloadAllCell];
|
||||
}
|
||||
|
||||
- (void)textFieldDidEndEditing:(UITextField *)textField
|
||||
{
|
||||
_ifNeedBeginEdit = NO;
|
||||
|
||||
if (self.textEditStatusChangeblock) {
|
||||
self.textEditStatusChangeblock(CRTextEditStatus_EndEdit);
|
||||
}
|
||||
|
||||
[self reloadAllCell];
|
||||
}
|
||||
|
||||
#pragma mark - TextViewEdit
|
||||
- (void)beginEdit{
|
||||
if (![self.textView isFirstResponder]) {
|
||||
[self.textView becomeFirstResponder];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)endEdit{
|
||||
if ([self.textView isFirstResponder]) {
|
||||
[self.textView resignFirstResponder];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clearAll
|
||||
{
|
||||
[self clearAllWithBeginEdit:YES];
|
||||
}
|
||||
|
||||
- (void)clearAllWithBeginEdit:(BOOL)beginEdit
|
||||
{
|
||||
_oldLength = 0;
|
||||
[_valueArr removeAllObjects];
|
||||
self.textView.text = @"";
|
||||
[self allSecurityClose];
|
||||
[self reloadAllCell];
|
||||
[self triggerBlock];
|
||||
|
||||
if (beginEdit) {
|
||||
[self beginEdit];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - UITextFieldDidChange
|
||||
- (void)textDidChange:(UITextField *)textField {
|
||||
[self baseTextDidChange:textField manualInvoke:NO];
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤输入内容
|
||||
*/
|
||||
- (NSString *)filterInputContent:(NSString *)inputStr {
|
||||
|
||||
NSMutableString *mutableStr = [[NSMutableString alloc] initWithString:inputStr];
|
||||
if (self.inputType == CRInputType_Number) {
|
||||
|
||||
/// 纯数字
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^0-9]" options:0 error:nil];
|
||||
[regex replaceMatchesInString:mutableStr options:0 range:NSMakeRange(0, [mutableStr length]) withTemplate:@""];
|
||||
} else if (self.inputType == CRInputType_Normal) {
|
||||
|
||||
/// 不处理
|
||||
nil;
|
||||
} else if (self.inputType == CRInputType_Regex) {
|
||||
|
||||
/// 自定义正则
|
||||
if (self.customInputRegex.length > 0) {
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:self.customInputRegex options:0 error:nil];
|
||||
[regex replaceMatchesInString:mutableStr options:0 range:NSMakeRange(0, [mutableStr length]) withTemplate:@""];
|
||||
}
|
||||
}
|
||||
|
||||
return [mutableStr copy];
|
||||
}
|
||||
|
||||
/**
|
||||
* textDidChange基操作
|
||||
* manualInvoke:是否为手动调用
|
||||
*/
|
||||
- (void)baseTextDidChange:(UITextField *)textField manualInvoke:(BOOL)manualInvoke {
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
NSString *verStr = textField.text;
|
||||
|
||||
//有空格去掉空格
|
||||
verStr = [verStr stringByReplacingOccurrencesOfString:@" " withString:@""];
|
||||
verStr = [self filterInputContent:verStr];
|
||||
|
||||
//自定义处理
|
||||
if (self.textCustomProcessblock) {
|
||||
verStr = self.textCustomProcessblock(verStr);
|
||||
}
|
||||
|
||||
if (verStr.length >= _codeLength) {
|
||||
verStr = [verStr substringToIndex:_codeLength];
|
||||
[self endEdit];
|
||||
}
|
||||
textField.text = verStr;
|
||||
|
||||
// 判断删除/增加
|
||||
CRBoxTextChangeType boxTextChangeType = CRBoxTextChangeType_NoChange;
|
||||
if (verStr.length > _oldLength) {
|
||||
boxTextChangeType = CRBoxTextChangeType_Insert;
|
||||
}else if (verStr.length < _oldLength){
|
||||
boxTextChangeType = CRBoxTextChangeType_Delete;
|
||||
}
|
||||
|
||||
// _valueArr
|
||||
if (boxTextChangeType == CRBoxTextChangeType_Delete) {
|
||||
[self setSecurityShow:NO index:_valueArr.count-1];
|
||||
[_valueArr removeLastObject];
|
||||
|
||||
}else if (boxTextChangeType == CRBoxTextChangeType_Insert){
|
||||
if (verStr.length > 0) {
|
||||
if (_valueArr.count > 0) {
|
||||
[self replaceValueArrToAsteriskWithIndex:_valueArr.count - 1 needEqualToCount:NO];
|
||||
}
|
||||
// NSString *subStr = [verStr substringWithRange:NSMakeRange(verStr.length - 1, 1)];
|
||||
// [strongSelf.valueArr addObject:subStr];
|
||||
[_valueArr removeAllObjects];
|
||||
|
||||
[verStr enumerateSubstringsInRange:NSMakeRange(0, verStr.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
[strongSelf.valueArr addObject:substring];
|
||||
}];
|
||||
|
||||
if (self.ifNeedSecurity) {
|
||||
if (manualInvoke) {
|
||||
// 处理所有秘文
|
||||
[self delaySecurityProcessAll];
|
||||
}else {
|
||||
// 只处理最后一个秘文
|
||||
[self delaySecurityProcessLastOne];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[self reloadAllCell];
|
||||
|
||||
_oldLength = verStr.length;
|
||||
|
||||
if (boxTextChangeType != CRBoxTextChangeType_NoChange) {
|
||||
[self triggerBlock];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Control security show
|
||||
- (void)setSecurityShow:(BOOL)isShow index:(NSInteger)index
|
||||
{
|
||||
if (index < 0) {
|
||||
NSAssert(NO, @"index必须大于等于0");
|
||||
return;
|
||||
}
|
||||
|
||||
CRBoxInputCellProperty *cellProperty = self.cellPropertyArr[index];
|
||||
cellProperty.ifShowSecurity = isShow;
|
||||
}
|
||||
|
||||
- (void)allSecurityClose
|
||||
{
|
||||
[self.cellPropertyArr enumerateObjectsUsingBlock:^(CRBoxInputCellProperty * _Nonnull cellProperty, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
if (cellProperty.ifShowSecurity == YES) {
|
||||
cellProperty.ifShowSecurity = NO;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)allSecurityOpen
|
||||
{
|
||||
[self.cellPropertyArr enumerateObjectsUsingBlock:^(CRBoxInputCellProperty * _Nonnull cellProperty, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
if (cellProperty.ifShowSecurity == NO) {
|
||||
cellProperty.ifShowSecurity = YES;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Trigger block
|
||||
- (void)triggerBlock
|
||||
{
|
||||
if (self.textDidChangeblock) {
|
||||
BOOL isFinished = _valueArr.count == _codeLength ? YES : NO;
|
||||
self.textDidChangeblock(_textView.text, isFinished);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Asterisk 替换密文
|
||||
/**
|
||||
* 替换密文
|
||||
* needEqualToCount:是否只替换最后一个
|
||||
*/
|
||||
- (void)replaceValueArrToAsteriskWithIndex:(NSInteger)index needEqualToCount:(BOOL)needEqualToCount
|
||||
{
|
||||
if (!self.ifNeedSecurity) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (needEqualToCount && index != _valueArr.count - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self setSecurityShow:YES index:index];
|
||||
}
|
||||
|
||||
#pragma mark 延时替换最后一个密文
|
||||
- (void)delaySecurityProcessLastOne
|
||||
{
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
[self delayAfter:self.securityDelay dealBlock:^{
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
if (strongSelf.valueArr.count > 0) {
|
||||
[strongSelf replaceValueArrToAsteriskWithIndex:strongSelf.valueArr.count-1 needEqualToCount:YES];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[strongSelf reloadAllCell];
|
||||
});
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark 延时替换所有一个密文
|
||||
- (void)delaySecurityProcessAll
|
||||
{
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
[self.valueArr enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
[strongSelf replaceValueArrToAsteriskWithIndex:idx needEqualToCount:NO];
|
||||
}];
|
||||
|
||||
[self reloadAllCell];
|
||||
}
|
||||
|
||||
#pragma mark - DelayBlock
|
||||
- (void)delayAfter:(CGFloat)delayTime dealBlock:(void (^)(void))dealBlock
|
||||
{
|
||||
dispatch_time_t timer = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime *NSEC_PER_SEC));
|
||||
dispatch_after(timer, dispatch_get_main_queue(), ^{
|
||||
if (dealBlock) {
|
||||
dealBlock();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - UICollectionViewDataSource
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
|
||||
{
|
||||
return _codeLength;
|
||||
}
|
||||
|
||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
id tempCell = [self customCollectionView:collectionView cellForItemAtIndexPath:indexPath];
|
||||
|
||||
if ([tempCell isKindOfClass:[CRBoxInputCell class]]) {
|
||||
|
||||
CRBoxInputCell *cell = (CRBoxInputCell *)tempCell;
|
||||
cell.ifNeedCursor = self.ifNeedCursor;
|
||||
|
||||
// CellProperty
|
||||
CRBoxInputCellProperty *cellProperty = self.cellPropertyArr[indexPath.row];
|
||||
cellProperty.index = indexPath.row;
|
||||
|
||||
NSString *currentPlaceholderStr = nil;
|
||||
if (_placeholderText.length > indexPath.row) {
|
||||
currentPlaceholderStr = [_placeholderText substringWithRange:NSMakeRange(indexPath.row, 1)];
|
||||
cellProperty.cellPlaceholderText = currentPlaceholderStr;
|
||||
}
|
||||
|
||||
// setOriginValue
|
||||
NSUInteger focusIndex = _valueArr.count;
|
||||
if (_valueArr.count > 0 && indexPath.row <= focusIndex - 1) {
|
||||
[cellProperty setMyOriginValue:_valueArr[indexPath.row]];
|
||||
}else{
|
||||
[cellProperty setMyOriginValue:@""];
|
||||
}
|
||||
|
||||
cell.boxInputCellProperty = cellProperty;
|
||||
|
||||
if (_ifNeedBeginEdit) {
|
||||
cell.selected = indexPath.row == focusIndex ? YES : NO;
|
||||
}else{
|
||||
cell.selected = NO;
|
||||
}
|
||||
}
|
||||
|
||||
return tempCell;
|
||||
}
|
||||
|
||||
- (void)reloadAllCell
|
||||
{
|
||||
[self.mainCollectionView reloadData];
|
||||
|
||||
NSUInteger focusIndex = _valueArr.count;
|
||||
/// 最后一个
|
||||
if (focusIndex == self.codeLength) {
|
||||
[self.mainCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:focusIndex - 1 inSection:0] atScrollPosition:UICollectionViewScrollPositionRight animated:YES];
|
||||
} else {
|
||||
[self.mainCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:focusIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Qiuck set
|
||||
- (void)quickSetSecuritySymbol:(NSString *)securitySymbol
|
||||
{
|
||||
if (securitySymbol.length != 1) {
|
||||
securitySymbol = @"✱";
|
||||
}
|
||||
|
||||
self.customCellProperty.securitySymbol = securitySymbol;
|
||||
}
|
||||
|
||||
#pragma mark - You can rewrite
|
||||
- (UICollectionViewCell *)customCollectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
CRBoxInputCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CRBoxInputCellID forIndexPath:indexPath];
|
||||
return cell;
|
||||
}
|
||||
|
||||
#pragma mark - Setter & Getter
|
||||
- (UITapGestureRecognizer *)tapGR
|
||||
{
|
||||
if (!_tapGR) {
|
||||
_tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(beginEdit)];
|
||||
}
|
||||
|
||||
return _tapGR;
|
||||
}
|
||||
|
||||
- (UICollectionView *)mainCollectionView
|
||||
{
|
||||
if (!_mainCollectionView) {
|
||||
_mainCollectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.boxFlowLayout];
|
||||
_mainCollectionView.showsHorizontalScrollIndicator = NO;
|
||||
_mainCollectionView.backgroundColor = [UIColor clearColor];
|
||||
_mainCollectionView.delegate = self;
|
||||
_mainCollectionView.dataSource = self;
|
||||
_mainCollectionView.layer.masksToBounds = YES;
|
||||
_mainCollectionView.clipsToBounds = YES;
|
||||
[_mainCollectionView registerClass:[CRBoxInputCell class] forCellWithReuseIdentifier:CRBoxInputCellID];
|
||||
}
|
||||
|
||||
return _mainCollectionView;
|
||||
}
|
||||
|
||||
- (CRBoxFlowLayout *)boxFlowLayout
|
||||
{
|
||||
if (!_boxFlowLayout) {
|
||||
_boxFlowLayout = [CRBoxFlowLayout new];
|
||||
_boxFlowLayout.itemSize = CGSizeMake(42, 47);
|
||||
}
|
||||
|
||||
return _boxFlowLayout;
|
||||
}
|
||||
|
||||
- (void)setCodeLength:(NSInteger)codeLength
|
||||
{
|
||||
_codeLength = codeLength;
|
||||
self.boxFlowLayout.itemNum = codeLength;
|
||||
}
|
||||
|
||||
- (void)setKeyBoardType:(UIKeyboardType)keyBoardType{
|
||||
_keyBoardType = keyBoardType;
|
||||
self.textView.keyboardType = keyBoardType;
|
||||
}
|
||||
|
||||
- (CRBoxTextView *)textView{
|
||||
if (!_textView) {
|
||||
_textView = [CRBoxTextView new];
|
||||
// _textView.alpha = 0.1;
|
||||
// _textView.tintColor = [UIColor clearColor];
|
||||
// _textView.backgroundColor = [UIColor clearColor];
|
||||
// _textView.textColor = [UIColor clearColor];
|
||||
_textView.delegate = self;
|
||||
[_textView addTarget:self action:@selector(textDidChange:) forControlEvents:UIControlEventEditingChanged];
|
||||
}
|
||||
return _textView;
|
||||
}
|
||||
|
||||
- (void)setTextContentType:(UITextContentType)textContentType
|
||||
{
|
||||
_textContentType = textContentType;
|
||||
|
||||
_textView.textContentType = textContentType;
|
||||
}
|
||||
|
||||
- (CRBoxInputCellProperty *)customCellProperty
|
||||
{
|
||||
if (!_customCellProperty) {
|
||||
_customCellProperty = [CRBoxInputCellProperty new];
|
||||
}
|
||||
|
||||
return _customCellProperty;
|
||||
}
|
||||
|
||||
- (NSMutableArray <CRBoxInputCellProperty *> *)cellPropertyArr
|
||||
{
|
||||
if (!_cellPropertyArr) {
|
||||
_cellPropertyArr = [NSMutableArray new];
|
||||
}
|
||||
|
||||
return _cellPropertyArr;
|
||||
}
|
||||
|
||||
- (NSString *)textValue
|
||||
{
|
||||
return _textView.text;
|
||||
}
|
||||
|
||||
@synthesize inputAccessoryView = _inputAccessoryView;
|
||||
- (void)setInputAccessoryView:(UIView *)inputAccessoryView
|
||||
{
|
||||
_inputAccessoryView = inputAccessoryView;
|
||||
self.textView.inputAccessoryView = _inputAccessoryView;
|
||||
}
|
||||
|
||||
- (UIView *)inputAccessoryView
|
||||
{
|
||||
return _inputAccessoryView;
|
||||
}
|
||||
|
||||
- (void)setIfNeedSecurity:(BOOL)ifNeedSecurity
|
||||
{
|
||||
_ifNeedSecurity = ifNeedSecurity;
|
||||
|
||||
if (ifNeedSecurity == YES) {
|
||||
[self allSecurityOpen];
|
||||
}else{
|
||||
[self allSecurityClose];
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self reloadAllCell];
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
16
keyBoard/Class/Vender/CRBoxInputView/CRBoxTextView.h
Normal file
16
keyBoard/Class/Vender/CRBoxInputView/CRBoxTextView.h
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// CRBoxTextView.h
|
||||
// CRBoxInputView
|
||||
//
|
||||
// Created by Chobits on 2019/1/3.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CRBoxTextView : UITextField
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
20
keyBoard/Class/Vender/CRBoxInputView/CRBoxTextView.m
Normal file
20
keyBoard/Class/Vender/CRBoxInputView/CRBoxTextView.m
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// CRBoxTextView.m
|
||||
// CRBoxInputView
|
||||
//
|
||||
// Created by Chobits on 2019/1/3.
|
||||
//
|
||||
|
||||
#import "CRBoxTextView.h"
|
||||
|
||||
@implementation CRBoxTextView
|
||||
|
||||
/**
|
||||
* /禁止可被粘贴复制
|
||||
*/
|
||||
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
52
keyBoard/Class/Vender/CRBoxInputView/CRLineView.h
Normal file
52
keyBoard/Class/Vender/CRBoxInputView/CRLineView.h
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// CRLineView.h
|
||||
// CRBoxInputView_Example
|
||||
//
|
||||
// Created by Chobits on 2019/6/10.
|
||||
// Copyright © 2019 BearRan. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#define CRColorMaster [UIColor colorWithRed:49/255.0 green:51/255.0 blue:64/255.0 alpha:1]
|
||||
|
||||
@interface CRLineView : UIView
|
||||
|
||||
typedef void(^CRLineViewSelectChangeBlock)(CRLineView *lineView, BOOL selected);
|
||||
|
||||
@property (strong, nonatomic) UIView *lineView;
|
||||
@property (assign, nonatomic) BOOL selected;
|
||||
|
||||
/**
|
||||
下划线颜色
|
||||
状态:未选中状态,且没有填充文字时
|
||||
默认:[UIColor colorWithRed:49/255.0 green:51/255.0 blue:64/255.0 alpha:1]
|
||||
*/
|
||||
@property (copy, nonatomic) UIColor *underlineColorNormal;
|
||||
|
||||
/**
|
||||
下划线颜色
|
||||
状态:选中状态时
|
||||
默认:[UIColor colorWithRed:49/255.0 green:51/255.0 blue:64/255.0 alpha:1]
|
||||
*/
|
||||
@property (copy, nonatomic) UIColor *underlineColorSelected;
|
||||
|
||||
/**
|
||||
下划线颜色
|
||||
状态:未选中状态,且有填充文字时
|
||||
默认:[UIColor colorWithRed:49/255.0 green:51/255.0 blue:64/255.0 alpha:1]
|
||||
*/
|
||||
@property (copy, nonatomic) UIColor *underlineColorFilled;
|
||||
|
||||
/**
|
||||
选择状态改变时回调
|
||||
*/
|
||||
@property (copy, nonatomic) CRLineViewSelectChangeBlock __nullable selectChangeBlock;
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame UNAVAILABLE_ATTRIBUTE;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
60
keyBoard/Class/Vender/CRBoxInputView/CRLineView.m
Normal file
60
keyBoard/Class/Vender/CRBoxInputView/CRLineView.m
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// CRLineView.m
|
||||
// CRBoxInputView_Example
|
||||
//
|
||||
// Created by Chobits on 2019/6/10.
|
||||
// Copyright © 2019 BearRan. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CRLineView.h"
|
||||
#import <Masonry/Masonry.h>
|
||||
|
||||
@interface CRLineView()
|
||||
{
|
||||
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CRLineView
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_underlineColorNormal = CRColorMaster;
|
||||
_underlineColorSelected = CRColorMaster;
|
||||
_underlineColorFilled = CRColorMaster;
|
||||
[self createUI];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)createUI
|
||||
{
|
||||
static CGFloat sepLineViewHeight = 4;
|
||||
|
||||
_lineView = [UIView new];
|
||||
[self addSubview:_lineView];
|
||||
_lineView.backgroundColor = _underlineColorNormal;
|
||||
_lineView.layer.cornerRadius = sepLineViewHeight / 2.0;
|
||||
[_lineView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.height.mas_equalTo(sepLineViewHeight);
|
||||
make.left.right.bottom.offset(0);
|
||||
}];
|
||||
|
||||
_lineView.layer.shadowColor = [[UIColor blackColor] colorWithAlphaComponent:0.2].CGColor;
|
||||
_lineView.layer.shadowOpacity = 1;
|
||||
_lineView.layer.shadowOffset = CGSizeMake(0, 2);
|
||||
_lineView.layer.shadowRadius = 4;
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected {
|
||||
_selected = selected;
|
||||
|
||||
if (self.selectChangeBlock) {
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
self.selectChangeBlock(weakSelf, selected);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
21
keyBoard/Class/Vender/CRBoxInputView/CRSecrectImageView.h
Normal file
21
keyBoard/Class/Vender/CRBoxInputView/CRSecrectImageView.h
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// CRSecrectImageView.h
|
||||
// CRBoxInputView_Example
|
||||
//
|
||||
// Created by Chobits on 2019/6/10.
|
||||
// Copyright © 2019 BearRan. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CRSecrectImageView : UIView
|
||||
|
||||
@property (strong, nonatomic) UIImage *image;
|
||||
@property (assign, nonatomic) CGFloat imageWidth;
|
||||
@property (assign, nonatomic) CGFloat imageHeight;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
65
keyBoard/Class/Vender/CRBoxInputView/CRSecrectImageView.m
Normal file
65
keyBoard/Class/Vender/CRBoxInputView/CRSecrectImageView.m
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// CRSecrectImageView.m
|
||||
// CRBoxInputView_Example
|
||||
//
|
||||
// Created by Chobits on 2019/6/10.
|
||||
// Copyright © 2019 BearRan. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CRSecrectImageView.h"
|
||||
#import <Masonry/Masonry.h>
|
||||
|
||||
@interface CRSecrectImageView()
|
||||
{
|
||||
UIImageView *_lockImgView;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation CRSecrectImageView
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self createUI];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)createUI
|
||||
{
|
||||
_lockImgView = [UIImageView new];
|
||||
_lockImgView.image = [UIImage imageNamed:@"smallLock"];
|
||||
[self addSubview:_lockImgView];
|
||||
[_lockImgView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.offset(0);
|
||||
make.centerY.offset(0);
|
||||
make.width.mas_equalTo(23);
|
||||
make.height.mas_equalTo(27);
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Setter & Getter
|
||||
- (void)setImage:(UIImage *)image
|
||||
{
|
||||
_image = image;
|
||||
_lockImgView.image = image;
|
||||
}
|
||||
|
||||
- (void)setImageWidth:(CGFloat)imageWidth
|
||||
{
|
||||
_imageWidth = imageWidth;
|
||||
[_lockImgView mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.mas_equalTo(imageWidth);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setImageHeight:(CGFloat)imageHeight
|
||||
{
|
||||
_imageHeight = imageHeight;
|
||||
[_lockImgView mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||
make.height.mas_equalTo(imageHeight);
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user