这是我的自定义键盘,我相信它可以在 Apple 允许的情况下完全解决这些问题:
// PVKeyboard.h
#import <UIKit/UIKit.h>
@interface PVKeyboard : UIView
@property (nonatomic,assign) UITextField *textField;
@end
// PVKeyboard.m
#import "PVKeyboard.h"
@interface PVKeyboard () {
UITextField *_textField;
}
@property (nonatomic,assign) id<UITextInput> delegate;
@end
@implementation PVKeyboard
- (id<UITextInput>) delegate {
return _textField;
}
- (UITextField *)textField {
return _textField;
}
- (void)setTextField:(UITextField *)tf {
_textField = tf;
_textField.inputView = self;
}
- (IBAction)dataPress:(UIButton *)btn {
[self.delegate insertText:btn.titleLabel.text];
}
- (IBAction)backPress {
if ([self.delegate conformsToProtocol:@protocol(UITextInput)]) {
[self.delegate deleteBackward];
} else {
int nLen = [_textField.text length];
if (nLen)
_textField.text = [_textField.text substringToIndex:nLen-1];
}
}
- (IBAction)enterPress {
[_textField.delegate textFieldShouldReturn:_textField];
}
- (UIView *)loadWithNIB {
NSArray *aNib = [[NSBundle mainBundle]loadNibNamed:NSStringFromClass([self class]) owner:self options:nil];
UIView *view = [aNib objectAtIndex:0];
[self addSubview:view];
return view;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self)
[self loadWithNIB];
return self;
}
@end
在 XCode 4.3 及更高版本中,您需要创建一个基于 UIView 的目标类(用于 .h 和 .m 文件)和一个用户界面视图文件(用于 .xib 文件)。确保所有三个文件具有相同的名称。使用身份检查器,确保设置 XIB 的文件所有者自定义类以匹配新对象的名称。使用属性检查器,将表单的大小设置为自由格式并将状态栏设置为无。使用 Size Inspector,设置表单的大小,它应该与标准键盘的宽度相匹配(iPhone 纵向为 320,iPhone 横向为 480),但您可以选择任何您喜欢的高度。
表格可以使用了。添加按钮并将它们连接到 dataPress、backPress 和 enterPress(视情况而定)。initWithFrame: 和 loadWithNIB 函数将发挥所有魔力,让您可以使用在 Interface Builder 中设计的键盘。
要将此键盘与 UITextField myTextField 一起使用,只需将以下代码添加到您的 viewDidLoad:
self.keyboard = [[PVKeyboard alloc]initWithFrame:CGRectMake(0,488,320,60)];
self.keyboard.textField = self.myTextField;
由于某些限制,此键盘不可重复使用,因此您需要每个字段一个。我几乎可以让它可重复使用,但我只是觉得没那么聪明。键盘也仅限于 UITextFields,但这主要是因为实现回车键功能的限制,我将在下面解释。
这是让您设计出比此入门框架更好的键盘的魔力...
我使用谨慎的离散设置器 (setTextField) 实现了这个键盘的唯一属性 textField,因为:
- 我们需要 UITextField 对象来处理输入问题
- 我们需要 UITextField,因为它符合符合 UIKeyInput 的 UITextInput 协议,它完成了我们大部分繁重的工作
- 这是一个方便的地方,可以将 UITextInput 的 inputView 字段设置为使用此键盘。
您会注意到另一个名为 delegate 的私有属性,它本质上将 UITextField 指针类型转换为 UITextInput 指针。我可能可以内联完成这个转换,但我觉得这可能对未来的扩展很有用,可能包括对 UITextView 的支持。
函数 dataPress 是使用 UIKeyInput 的 insertText 方法在编辑字段中插入文本。这似乎适用于 iOS 4 的所有版本。对于我的键盘,我只是使用每个按钮的标签,这很正常。使用任何你喜欢的 NSStrings。
函数 dataBack 执行退格操作,并且稍微复杂一些。当 UIKeyInput deleteBackward 工作时,它工作得非常好。虽然文档说它可以回溯到 iOS 3.2,但它似乎只能回溯到 iOS 5.0,也就是 UITextField(和 UITextView)符合 UITextInput 协议的时候。所以在此之前,你是靠自己的。由于 iOS 4 支持是许多人关心的问题,我实现了一个蹩脚的退格键,它直接在 UITextField 上工作。如果不是因为这个要求,我可以让这个键盘与 UITextView 一起工作。而且这个退格不是一般的,只删除最后一个字符,而deleteBackward即使用户移动光标也能正常工作。
函数 enterPress 实现了 enter 键,但它是一个完整的组合,因为 Apple 似乎没有提供调用 enter 键的方法。因此 enterPress 只需调用 UITextField 的委托函数 textFieldShouldReturn:,这是大多数程序员实现的。请注意,这里的委托是 UITextField 的 UITextFieldDelegate 而不是键盘本身的委托属性。
这个解决方案绕过了正常的键盘处理,这在 UITextField 的情况下几乎不重要,但是使这种技术无法用于 UITextView,因为现在可以在正在编辑的文本中插入换行符。
差不多就是这样。完成这项工作需要 24 小时的阅读和整理。我希望它可以帮助某人。