This commit is contained in:
2025-12-02 18:29:04 +08:00
parent cafde48f4a
commit 8245e7b3d1
32 changed files with 2485 additions and 6 deletions

View 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

View 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

View 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

View 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

View 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 符号类型根据securitySymboloriginValue的内容来显示
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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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