且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在iOS应用程序上从自定义键盘检索击键?

更新时间:2023-02-03 09:30:01

这是我的自定义键盘,我相信这些键盘完全符合Apple的要求:

Here's my custom keyboard which I believe addresses these as completely as Apple will allow:

//  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的Objective-Class(用于.h和.m文件)和用户界面视图文件(用于.xib文件)。确保所有三个文件具有相同的名称。使用Identity Inspector,确保设置XIB的文件所有者自定义类以匹配新对象的名称。使用Attributes Inspector,将表单的大小设置为Freeform,并将状态栏设置为none。使用尺寸检查器,设置表格的大小,该尺寸应与标准键盘的宽度相匹配(iPhone纵向为320,iPhone横向为480),但您可以选择任何您喜欢的高度。

In XCode 4.3 and later, you need to create an objective-Class (for the .h & .m files) based on UIView and a User Interface View file (for the .xib file). Make sure all three files have the same name. Using the Identity Inspector, make sure to set the XIB's File's Owner Custom Class to match the new object's name. Using the Attributes Inspector, set the form's size to Freeform and set the Status Bar to none. Using the Size Inspector, set the form's size, which should match the width of the standard keyboard (320 for iPhone portrait and 480 for iPhone landscape), but you can choose any height you like.

表格已准备好使用。添加按钮并根据需要将它们连接到dataPress,backPress和enterPress。 initWithFrame:和loadWithNIB函数将完全允许您使用在Interface Builder中设计的键盘。

The form is ready to be used. Add buttons and connect them to the dataPress, backPress and enterPress as appropriate. The initWithFrame: and loadWithNIB functions will do all the magic to allow you to use a keyboard designed in Interface Builder.

要将此键盘与UITextField myTextField一起使用,只需添加下面的代码以您的viewDidLoad中:

To use this keyboard with a UITextField myTextField, just add the following code to your viewDidLoad:

self.keyboard = [[PVKeyboard alloc]initWithFrame:CGRectMake(0,488,320,60)];
self.keyboard.textField = self.myTextField;

由于某些限制,此键盘不可重复使用,因此每个字段需要一个键盘。我几乎可以让它重复使用,但我只是觉得不那么聪明。键盘也仅限于UITextFields,但这主要是因为实现回车键功能的限制,我将在下面解释。

Because of some limitations, this keyboard isn't reusable, so you'll need one per field. I can almost make it reusable, but I'm just not feeling that clever. The keyboard is also limited to UITextFields, but that's mainly because of limitations in implementing the enter key functionality, which I'll explain below.

这是应该允许你的魔力设计一个比这个入门框架更好的键盘...

Here's the magic that should allow you to design a better keyboard than this starter framework...

我已经使用谨慎的离散设置器(setTextField)实现了这个键盘textField的唯一属性,因为:

I've implemented the only property of this keyboard, textField, using a discreet a discrete setter (setTextField) because:


  1. 我们需要UITextField对象来处理输入问题

  2. 我们需要UITextField,因为它符合UITextInput协议符合UIKeyInput,它完成了很多繁重工作

  3. 这是设置UITextInput的inputView字段以使用此键盘的一个方便的地方。

您会注意到第二个名为delegate的私有属性,它实质上是将UITextField指针强制转换为UITextInput指针。我可能已经完成了这个内联,但我觉得这可能是一个有用的未来扩展功能,也许包括对UITextView的支持。

You'll notice a second private property named delegate, which essentially typecasts the UITextField pointer to a UITextInput pointer. I probably could have done this cast inline, but I sensed this might be useful as a function for future expansion, perhaps to include support for UITextView.

函数dataPress是什么使用UIKeyInput的insertText方法插入文本输入已编辑的字段。这似乎适用于所有版本的iOS 4.对于我的键盘,我只是使用每个按钮的标签,这是很正常的。使用任何NSStrings打击你的想法。

The function dataPress is what inserts text input the edited field using the insertText method of UIKeyInput. This seems to work in all versions back to iOS 4. For my keyboard, I'm simply using the label of each button, which is pretty normal. Use whatever NSStrings strike your fancy.

函数dataBack执行退格并且稍微复杂一些。当UIKeyInput deleteBackward工作时,它运行得非常好。虽然文档说它可以回溯到iOS 3.2,但它似乎只能回到iOS 5.0,这是UITextField(和UITextView)符合UITextInput协议的时候。所以在此之前,你是独立的。由于iOS 4支持是许多人关注的问题,我已经实现了一个可以直接在UITextField上运行的蹩脚退格。如果没有这个要求,我可以让这个键盘与UITextView一起使用。并且这个退格区不是一般的,只删除最后一个字符,而即使用户移动光标,deleteBackward也能正常工作。

The function dataBack does the backspace and is a little more complicated. When the UIKeyInput deleteBackward works, it works wonderfully. And while the documentation says it works back to iOS 3.2, it seems to only work back to iOS 5.0, which is when UITextField (and UITextView) conformed to the UITextInput protocol. So prior to that, you're on your own. Since iOS 4 support is a concern to many, I've implemented a lame backspace which works on the UITextField directly. If not for this requirement, I could have made this keyboard work with UITextView. And this backspace isn't as general, only deleting the last character, while deleteBackward will work properly even if the user moves the cursor.

函数enterPress实现了回车键,但它是一个完整的kludge,因为Apple似乎没有给出一个调用enter键的方法。因此,enterPress只调用UITextField的委托函数textFieldShouldReturn:,这是大多数程序员实现的。请注意,这里的委托是UITextField的UITextFieldDelegate而不是键盘本身的委托属性。

The function enterPress implements the enter key, but is a complete kludge because Apple doesn't seem to give a method for invoking the enter key. So enterPress simply calls the UITextField's delegate function textFieldShouldReturn:, which most programmers implement. Please note that the delegate here is the UITextFieldDelegate for the UITextField and NOT the delegate property for the keyboard itself.

这个解决方案围绕正常的键盘处理,这几乎不重要UITextField的情况,但是这种技术在UITextView中无法使用,因为现在可以在正在编辑的文本中插入换行符。

This solution goes around the normal keyboard processing, which hardly matters in the case of UITextField, but makes this technique unusable with UITextView since there is now way to insert line breaks in the text being edited.

这就是它。这需要24小时的阅读和拼凑来完成这项工作。我希望它有所帮助。

That's pretty much it. It took 24 hours of reading and cobbling to make this work. I hope it helps somebody.