在开发中经常碰到一些会用到自定义的数字键盘的,这些一般都是随机或者按照一定的规则来生成的数字键盘,这段时间刚好有这个需求所以就写了一个先看下效果
Untitled.gif先说一下实现思路:
其实开发这种键盘很简单的,直接自定义一个UITextField 的 inputView就行了, 这个自定的view上面是一个toolbar 下面则是用的 collectionview 然后处理点击事件来控制输入效果
那接下来我们来看一下实现过程:
首先我们先来实现自定义的View
- (void)setupComponents
{
self.bounds = CGRectMake(0, 0, self.bounds.size.width, kKeyBoardHeight);
[self setupToolBar];
[self setupCollectionView];
}
-(void)setupToolBar
{
UIToolbar *toolBar = [UIToolbar new];
toolBar.backgroundColor = [UIColor groupTableViewBackgroundColor];
[self addSubview:toolBar];
UIImageView *safeImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"keyboard_safe"]];
[toolBar addSubview:safeImage];
UILabel *safeLabel = [UILabel new];
safeLabel.textAlignment = NSTextAlignmentCenter;
safeLabel.text = @"安全键盘";
safeLabel.textColor = self.fontColor;
safeLabel.font = [UIFont systemFontOfSize:15];
[toolBar addSubview:safeLabel];
UIBarButtonItem *flexibleBarBtnItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *finishInputBarBtnItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneBtnClick)];
toolBar.tintColor = [UIColor blackColor];
toolBar.items = @[flexibleBarBtnItem, finishInputBarBtnItem];
[toolBar mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self);
make.leading.equalTo(self);
make.trailing.equalTo(self);
make.height.mas_equalTo(KToolBarViewHeight);
}];
[safeImage mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(15.0f, 17.0f));
make.centerY.equalTo(toolBar);
make.trailing.equalTo(safeLabel.mas_leading).offset(-6.0f);
}];
[safeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(CGSizeMake(toolBar.center.x+11.0f, toolBar.center.y));
}];
}
-(void)setupCollectionView
{
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.minimumInteritemSpacing = self.itemSpace;
flowLayout.minimumLineSpacing = self.itemSpace;
flowLayout.sectionInset = UIEdgeInsetsMake(self.itemSpace, 0, -self.itemSpace, 0);
flowLayout.itemSize = CGSizeMake(kItemWidth, kItemHeight);
_keyboardView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, KToolBarViewHeight, [UIScreen mainScreen].bounds.size.width, self.frame.size.height - KToolBarViewHeight) collectionViewLayout:flowLayout];
_keyboardView.backgroundColor = [UIColor groupTableViewBackgroundColor];
_keyboardView.delaysContentTouches = NO;
_keyboardView.dataSource = self;
_keyboardView.delegate = self;
[self addSubview:_keyboardView];
[_keyboardView registerClass:[SafeKeyboardImageCell class] forCellWithReuseIdentifier:NSStringFromClass([SafeKeyboardImageCell class])];
[_keyboardView registerClass:[SafeKeyboardTextCell class] forCellWithReuseIdentifier:NSStringFromClass([SafeKeyboardTextCell class])];
}
这里很简单就是UI的搭建 用到了masonry来自动布局的,但这里我们是自己添加的toolbar,里面有一个完成按钮,收键盘用的,如果你用到了IQKeyBoardManager等这种键盘控制的三方库的可能需要做一下兼容没因为他们也自动加了一个toolbar 例如:IQKeyBoardManager
-(void)textFieldBeginEditing
{
if (randomKeyboard && changeWhenAppear)
{
[self refresh];
}
//如果用到了IQKeyboardManager
[IQKeyboardManager sharedManager].enableAutoToolbar = NO;
}
-(void)textFieldEndEditing
{
//如果用到了IQKeyboardManager
[IQKeyboardManager sharedManager].enableAutoToolbar = YES;
}
接下来就是数据源了:
使用随机排序的数据源
- (void)refresh
{
if (randomKeyboard)
{
[_titleArr removeAllObjects];
NSMutableArray *startArray=[[NSMutableArray alloc] initWithObjects:@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",nil];
NSMutableArray *resultArray = [[NSMutableArray alloc] initWithCapacity:0];
NSInteger m = 10;
for (int i=0; i<m; i++)
{
int t=arc4random()%startArray.count;
resultArray[i] = startArray[t];
startArray[t] = [startArray lastObject];
[startArray removeLastObject];
}
[resultArray insertObject:@"C" atIndex:9];
[resultArray insertObject:@"D" atIndex:11];
_titleArr = resultArray;
}
else
{
_titleArr = [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"C",@"0",@"D"]];
}
[_keyboardView reloadData];
}
然后处理点击事件
- (void)showInputWithNumberStr:(NSString *)numStr
{
if ([@"C" isEqualToString:numStr])
{
_textField.text = @"";
_safeKeyboardDidChangedBlock ? _safeKeyboardDidChangedBlock(_textField.text) : nil;
}
else if([@"D" isEqualToString:numStr])
{
[_textField deleteBackward];
}
else
{
[_textField insertText:numStr];
}
}
最后设置UITextField的inputView为我们自定义的view就OK了
- (instancetype)initWithTextField:(UITextField *)textField
{
if (self = [super init])
{
_textField = textField;
_textField.inputView = self;
[_textField addTarget:self action:@selector(textFieldChangedEditing) forControlEvents:UIControlEventEditingChanged];
[_textField addTarget:self action:@selector(textFieldBeginEditing) forControlEvents:UIControlEventEditingDidBegin];
[_textField addTarget:self action:@selector(textFieldEndEditing) forControlEvents:UIControlEventEditingDidEnd];
}
控件中已经给出2个自定义需求的参数,需要的同学可以直接修改就行,其中第二个参数changeWhenAppear这个是表示每次键盘出现都随机排序键盘,设置为NO的话,键盘只在实例化的时候随机一次后面都是按这个随机排序出现的,你点击收起再弹出来排序不变
const static BOOL randomKeyboard = YES;//是否使用随机键盘
const static BOOL changeWhenAppear = YES;//每次键盘出现都改变随机(随机键盘才有效)
控件我简单的封装了下,需要的小伙伴拿去吧
网友评论