Here's my custom keyboard, which I believe is addressed to them completely, like 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
In Xcode 4.3 and later, you need to create an object class (for .h and .m files) based on a UIView file and a user interface file (for a .xib file). Make sure all three files have the same name. Using the Identity Inspector, verify that the user class of the owner of the XIB file matches the name of the new object. Using the Attributes Inspector, set the size of the form in Freeform and set the status bar to none. Using the Size Inspector, set the size of the form to fit the width of the standard keyboard (320 for iPhone and 480 for iPhone), but you can choose any height you need.
The form is ready to use. Add buttons and connect them to dataPress, backPress and enterPress, if necessary. The initWithFrame: and loadWithNIB functions will do all the magic so you can use the keyboard developed in Interface Builder.
To use this keyboard with a UITextField myTextField, simply add the following code to your viewDidLoad:
self.keyboard = [[PVKeyboard alloc]initWithFrame:CGRectMake(0,488,320,60)]; self.keyboard.textField = self.myTextField;
Due to some restrictions, this keyboard cannot be reused, so you will need one field. I can almost make it reusable, but I just don't feel this smart. The keyboard is also limited by UITextFields, but mainly due to limitations in the implementation of function input keys, which I will explain below.
Here is the magic that should allow you to create a better keyboard than this starting frame ...
I implemented the only property of this textField keyboard using a discrete discrete setter (setTextField), because:
- we need a UITextField object to handle input problems
- we need a UITextField because it conforms to the UITextInput protocol, which conforms to UIKeyInput, which does most of our heavy lifting
- It was a convenient place to set the Input UITextInput input field to use this keyboard.
You will see a second private property called delegate, which essentially outputs a UITextField pointer to a UITextInput pointer. Maybe I could do this, but I realized that it might be useful as a function for future extensions, perhaps to include support for UITextView.
The dataPress function is that it inserts text, enters an edited field using the insertText method for UIKeyInput. This seems to work in all versions for iOS 4. For my keyboard, I just use the label of each button, which is pretty normal. Use all that NSStrings amazes with your imagination.
The dataBack function does inverse space and is a bit more complicated. When UIKeyInput deleteBackward works, it works wonderfully. And although the documentation says that it works with iOS 3.2, it looks like it only works with iOS 5.0 when the UITextField (and UITextView) conforms to the UITextInput protocol. Therefore, before that, you yourself. Since iOS 4 support is a problem for many, I have implemented a lame backspace that works directly with UITextField. If not for this requirement, I could make this keyboard work with UITextView. And this backspace is not common, it only deletes the last character, and deleteBackward will work correctly even if the user moves the cursor.
The enterPress function implements an input key, but is a complete kludge because Apple does not seem to provide a method for invoking an input key. Thus, enterPress simply calls the UITextField textFieldShouldReturn: delegate function, which most programmers implement. Note that the delegate here is UITextFieldDelegate for UITextField and NOT a delegate property for the keyboard itself.
This solution extends to normal keyboard processing, which is hardly relevant in the case of UITextField, but makes this technique unsuitable for use with UITextView, as there is now a way to insert line breaks in editable text.
This is pretty much the case. This work required 24 hours of reading and paving. Hope this helps someone.