这个键盘可以在界面上随意拖动,有三个文件, SWKNumberKeyBoard,xib,SWKNumberKeyBoard.h ,SWKNumberKeyBoard.m
其中在SWKNumberKeyBoard.h文件中;
#import <UIKit/UIKit.h>
@class SWKNumberKeyBoard;
// keycode的定义
#define CUSTOM_KEY_CODE_UP 30 // ↑
#define CUSTOM_KEY_CODE_DOWN 31 // ↓
#define CUSTOM_KEY_CODE_LEFT 32 // ←
#define CUSTOM_KEY_CODE_RIGHT 33 // →
#define CUSTOM_KEY_CODE_CLOSE 50 // 关闭
#define CUSTOM_KEY_CODE_CLEAR 51 // 清除
/** 键盘操作的通知代理 */
@protocol SWKNumberKeyBoardDelegate <NSObject>
@required
/** 代理方法 */
- (void)keyboard:(SWKNumberKeyBoard *)keyboard onTouchNumber:(NSString*)number;
- (void)keyboard:(SWKNumberKeyBoard *)keyboard onTouchControl:(NSInteger)customKeyCode;
@end
@interface SWKNumberKeyBoard : UIView
// delegate
@property (weak, nonatomic) id<SWKNumberKeyBoardDelegate> delegate;
// 表示显示中的值
@property (readonly) BOOL isOpen;
//用来显示的方法
- (void)show:(UIView*)appView :(CGRect*)initStrInfo;
// 关闭方法
- (void)close;
@end
在SWKNumberKeyBoard.m方法中;
#import "SWKNumberKeyBoard.h"
// 按钮的tag的为10
static const NSInteger kCustomKeyCoad_Dot = 10; // [.]
// 默认的位置
static const NSInteger kDefaultOrigin_X = 10;
static const NSInteger kDefaultOrigin_Y = 300;
@interface SWKNumberKeyBoard() {
// 定义成私有的
@private
UIView *parentView;
UIGestureRecognizer *panGes;
}
// xib的各个控件
@property (weak, nonatomic) IBOutlet UIView *keyboardView;
@property (weak, nonatomic) IBOutlet UIButton *btnClose;
@property (weak, nonatomic) IBOutlet UIButton *btnClear;
@property (weak, nonatomic) IBOutlet UIButton *btnOne;
@property (weak, nonatomic) IBOutlet UIButton *btnTwo;
@property (weak, nonatomic) IBOutlet UIButton *btnThree;
@property (weak, nonatomic) IBOutlet UIButton *btnFour;
@property (weak, nonatomic) IBOutlet UIButton *btnFive;
@property (weak, nonatomic) IBOutlet UIButton *btnSix;
@property (weak, nonatomic) IBOutlet UIButton *btnSeven;
@property (weak, nonatomic) IBOutlet UIButton *btnEight;
@property (weak, nonatomic) IBOutlet UIButton *btnNine;
@property (weak, nonatomic) IBOutlet UIButton *btnZero;
@property (weak, nonatomic) IBOutlet UIButton *btnDot;
@property (weak, nonatomic) IBOutlet UIButton *btnUp;
@property (weak, nonatomic) IBOutlet UIButton *btnDown;
@property (weak, nonatomic) IBOutlet UIButton *btnLeft;
@property (weak, nonatomic) IBOutlet UIButton *btnRight;
@end
@implementation SWKNumberKeyBoard
-(instancetype)init{
self = [super init];
if(self){
// 读取 nib
NSString *classNeme = NSStringFromClass([self class]);
self = [[NSBundle mainBundle] loadNibNamed:classNeme owner:self options:nil][0];
_isOpen = NO;
}
return self;
}
//[_numKeyboard show:self.view : nil]; 在另一个控制器会将这个方法实现传入self.view,使这个键盘在控制器中显示
- (void)show:(UIView*)appView :(CGRect *)oriRect {
// 移动拖动的时候UIGestureRecognizer的生成
parentView = appView;
panGes = [[UIPanGestureRecognizer alloc]initWithTarget:self
action:@selector(panAction:)];
[parentView addGestureRecognizer:panGes];
//设置键盘开始的位置
CGRect setFrame = CGRectMake(kDefaultOrigin_X,
kDefaultOrigin_Y,
self.frame.size.width,
self.frame.size.height);
//如果oriRect不为空就显示当前的位置
if (oriRect!=nil){
setFrame.origin.x = oriRect->origin.x;
setFrame.origin.y = oriRect->origin.y;
}
self.frame = setFrame;
[parentView addSubview:self];
// 表示键盘显示了
_isOpen = YES;
}
- (void)close {
[parentView removeGestureRecognizer:panGes]; // UIGestureRecognizer删除
[self removeFromSuperview];
// 表示键盘不显示
_isOpen = NO;
}
// 只包含各个数字的键盘按钮
- (IBAction)onTouchNumber:(UIButton *)sender {
// 按钮的tag
NSString *ret = [NSString stringWithFormat:@"%ld", (long)sender.tag];
// [.]键的情况下,将tag为10的键盘按钮换为 .
if ([ret isEqualToString:[NSString stringWithFormat:@"%ld", (long)kCustomKeyCoad_Dot]]) ret = @".";
// 实现代理方法
[self.delegate keyboard:self onTouchNumber:ret];
}
//上下左右,清除,关闭的按钮的点击事件
- (IBAction)onTouchControl:(UIButton *)sender {
// 实现代理方法
[self.delegate keyboard:self onTouchControl:sender.tag];
}
/** 拖动的时候会调用这个方法 */
- (void) panAction:(UIPanGestureRecognizer *)pan {
// 得到移动的距离
CGPoint point = [pan translationInView:parentView];
// 加上移动的距离,使键盘得到现在的位置
CGPoint movedPoint = CGPointMake(self.center.x + point.x,
self.center.y + point.y);
self.center = movedPoint;
// 移动后的距离进行初始化,不这样做的话,
// [pan translationInView:]返回的距离会一直加上去。
[pan setTranslation:CGPointZero
inView:parentView];
}
@end
在另一个控制器中实现上面的代理方法
/** 找到输入的对象 */
- (UIView *)findFirstResponder:(UIView *)view
{
if (view.isFirstResponder) {
return view;
}
for (UIView *subView in view.subviews) {
if ([subView isFirstResponder]) {
return subView;
}
UIView *responder = [self findFirstResponder:subView];
if (responder) {
return responder;
}
}
return nil;
}
/** 关闭键盘 */
- (void)closeNumberKeybord {
// 关闭键盘,close是SWKViewController里面的一个方法
[_numKeyboard close];
// 其他的,无须关心
[self.view removeGestureRecognizer:_singleTap];
[self.view endEditing:YES];
}
/** 像右移动 */
- (void)moveToNextResponder
{
if (self.numberOfNewTF.isFirstResponder)
{
[self.numberOfMorningTF becomeFirstResponder];
}
else if (self.numberOfMorningTF.isFirstResponder)
{
[self.numberOfPlanTF becomeFirstResponder];
}
else if (self.numberOfPlanTF.isFirstResponder)
{
[self.numberOfResultTF becomeFirstResponder];
}
}
/** 像左移动 ,numberOfNewTF等都是相应的textField */
- (void)moveToPreviousResponder
{
if (self.numberOfMorningTF.isFirstResponder)
{
[self.numberOfNewTF becomeFirstResponder];
}
else if (self.numberOfPlanTF.isFirstResponder)
{
[self.numberOfMorningTF becomeFirstResponder];
}
else if (self.numberOfResultTF.isFirstResponder)
{
[self.numberOfPlanTF becomeFirstResponder];
}
}
/** ([0]~[9]和[.])的点击事件用的方法 */
- (void)keyboard:(SWKNumberKeyBoard *)keyboard onTouchNumber:(NSString*)number
{
// 找到输入的地方
UIView *firstResponder = [self findFirstResponder:self.view];
if ((firstResponder)
&& ([firstResponder isKindOfClass:[UITextField class]]))
{
// 插入数据
[(UITextField *)firstResponder insertText:number];
}
}
/** ([关闭]と[清除]と方向键)的点击事件用的方法 */
- (void)keyboard:(SWKNumberKeyBoard *)keyboard onTouchControl:(NSInteger)customKeyCode{
if (customKeyCode == CUSTOM_KEY_CODE_CLOSE)
{
[self closeNumberKeybord];
}
else if (customKeyCode == CUSTOM_KEY_CODE_CLEAR)
{
UIView *firstResponder = [self findFirstResponder:self.view];
if ((firstResponder)
&& ([firstResponder isKindOfClass:[UITextField class]]))
{
((UITextField *)firstResponder).text = @"";
}
}
else
{
// 输入的对象移动了
UIView *firstResponder = [self findFirstResponder:self.view];
if (firstResponder)
{
// 下一个
UIResponder *responder = firstResponder.nextResponder;
while (responder) {
if ([responder isEqual:self])
{
if (customKeyCode == CUSTOM_KEY_CODE_LEFT)
{
[self moveToPreviousResponder];
}
else if (customKeyCode == CUSTOM_KEY_CODE_RIGHT)
{
[self moveToNextResponder];
}
break;
}
else if ([responder isKindOfClass:[SWKTableViewCell class]])
{
SWKTableViewCell *cell = (SWKTableViewCell *)responder;
switch (customKeyCode) {
case CUSTOM_KEY_CODE_UP:
// 上
[cell moveToUpperCell:firstResponder];
break;
case CUSTOM_KEY_CODE_DOWN:
// 下
[cell moveToDownerCell:firstResponder];
break;
case CUSTOM_KEY_CODE_LEFT:
// 左
[cell moveToPreviousResponder];
break;
case CUSTOM_KEY_CODE_RIGHT:
// 右
[cell moveToNextResponder];
break;
default:
break;
}
break;
}
// 这部分的好像没用到
else if ([responder isKindOfClass:[SWKSubViewController class]])
{
SWKSubViewController *subVC = (SWKSubViewController *)responder;
//
if (customKeyCode == CUSTOM_KEY_CODE_LEFT)
{
[subVC moveToPreviousResponder];
}
else if (customKeyCode == CUSTOM_KEY_CODE_RIGHT)
{
[subVC moveToNextResponder];
}
break;
}
responder = responder.nextResponder;
}
}
}
}
#import <UIKit/UIKit.h>
#import "SWKCellViewModel.h"
@protocol SWKCellDelegate<NSObject>
@optional
/** 向上的移动 */
- (void) cell:(UITableViewCell *)cell onMoveToUpper:(UIView *)currentResponder;
/** 下 */
- (void) cell:(UITableViewCell *)cell onMoveToDowner:(UIView *)currentResponder;
@end
@interface SWKTableViewCell : UITableViewCell
/** SWKCellDelegate */
@property (nonatomic, weak) id<SWKCellDelegate> delegate;
/** ViewModel */
@property (nonatomic) SWKCellViewModel *viewModel;
- (void)moveToNextResponder;
- (void)moveToPreviousResponder;
- (void)moveFromOtherCell:(UIView *)currentResponder;
- (void)moveToUpperCell:(UIView *)currentResponder;
- (void)moveToDownerCell:(UIView *)currentResponder;
@end
#import "SWKTableViewCell.h"
@implementation SWKTableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)moveToNextResponder
{
}
- (void)moveToPreviousResponder
{
}
- (void)moveFromOtherCell:(UIView *)currentResponder
{
}
- (void)moveToUpperCell:(UIView *)currentResponder
{
if ((self.delegate)
&& ([self.delegate respondsToSelector:@selector(cell:onMoveToUpper:)]))
{
[self.delegate cell:self onMoveToUpper:currentResponder];
}
}
- (void)moveToDownerCell:(UIView *)currentResponder
{
if ((self.delegate)
&& ([self.delegate respondsToSelector:@selector(cell:onMoveToDowner:)]))
{
[self.delegate cell:self onMoveToDowner:currentResponder];
}
}
@end
- (void)moveToTargetCellAsync:(UIView *)currentResponder targetPath:(NSIndexPath *)targetPath
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UITableViewCell *blockCell = nil;
int cnt = 0;
while (blockCell == nil)
{
blockCell = [self.tableView cellForRowAtIndexPath:targetPath];
cnt++;
if (cnt > 10)
{
break;
}
usleep(50000);
}
if (blockCell)
{
dispatch_async(dispatch_get_main_queue(), ^{
[((SWKTableViewCell *)blockCell) moveFromOtherCell:currentResponder];
});
}
});
}
//////////////////////////////////
/** 从别的cell移动到当前cell的情况 */
- (void)moveFromOtherCell:(UIView *)currentResponder
{
if ([_numberOfNewTF_CL.accessibilityIdentifier isEqualToString:currentResponder.accessibilityIdentifier])
{
[_numberOfNewTF_CL becomeFirstResponder];
}
else if ([_numberOfMorningTF_CL.accessibilityIdentifier isEqualToString:currentResponder.accessibilityIdentifier])
{
[_numberOfMorningTF_CL becomeFirstResponder];
}
else if ([_numberOfPlansHourTF_CL.accessibilityIdentifier isEqualToString:currentResponder.accessibilityIdentifier])
{
[_numberOfPlansHourTF_CL becomeFirstResponder];
}
else if ([_numberOfResultsHourTF_CL.accessibilityIdentifier isEqualToString:currentResponder.accessibilityIdentifier])
{
[_numberOfResultsHourTF_CL becomeFirstResponder];
}
else if ([_numberOfPlansTF_CL.accessibilityIdentifier isEqualToString:currentResponder.accessibilityIdentifier])
{
[_numberOfPlansTF_CL becomeFirstResponder];
}
else if ([_numberOfResultsTF_CL.accessibilityIdentifier isEqualToString:currentResponder.accessibilityIdentifier])
{
[_numberOfResultsTF_CL becomeFirstResponder];
}
}