views:

1583

answers:

6

Hi,

I need (i.e. a customer requirement) to provide a custom keyboard for the user to type text into both text fields and areas. I already have something that does the keyboard and appends test to a text field, however I'd like to make it more generic and have it act like the standard iphone keyboard, i.e. appear when teh user selects an editable text control. Currently my controller knows the target and the target is uneditable to prevent the standard keyboard.

Is there a way to hook into the behavior of text controls so I use my own keyboard easily?

Thanks, Vic

+1  A: 

Don't do it, man!

First, there's no way you'd get into the app store.

Second, there's no way you'd do a better job than Apple. They spent years of time and millions of dollars designing and implementing that keyboard.

Third, you can't do it without subclassing every text input control to use your own keyboard.

Finally, your customers will complain because they have your non-standard, not as good version. Poor app store ratings will kill your app!

Sometimes you need to have the balls to turn around to your customer and say that you can't implement what they want. Sure, you can technically achieve it, but just because you can doesn't mean you should.

iKenndac
We are using an iPhone to prototype touch interfaces, the hardware is cheaper and easier to try out.
vickirk
Well, in that case you'll probably have to subclass each input control and override -becomeFirstResponder to show your keyboard instead.
iKenndac
A: 

It depends how custom you want it. I personally wanted a numeric only keyboard, but didn't like the number pad, so I used the standard keyboard and added in a standard filter, which is part of the options, which rejects all the key presses that aren't numbers or space or delete.

I can't say whether Apple would like this though, and you're going to have a very hard time writing your own behavior that acts like the other keyboards. So much so, that it should be declared a bad idea.

update based on your comment it sounds more like you just need to create a view with a lot of buttons on it, and move this view around with the animate option turned on. It could then sort of slide up from the bottom like a keyboard and slide away again when dismissed.

dlamblin
Unfortunately the keyboard we need is not really a just a keyboard with characters on it, it has a few chars on it (true teh rest could be hidden in this mannner) but there are buttons that do a lot more than typing a single char. True I could add buttons elsewhere but it would be counter-intuative and look awful. I already have the keyboard working as required, I just need to wire it in easily, just wished the touch stuff on android was as stable a target as the ipod :-(
vickirk
+4  A: 

As long as you're not submitting your app to the app store, you can use a technique called method swizzling to dynamically replace methods of core classes at runtime. For example:

@interface UIControl(CustomKeyboard)
- (BOOL)__my__becomeFirstResponder
@end

@implementation UIControl(CustomKeyboard)
- (BOOL)__my__becomeFirstResponder
{
    BOOL becameFirstResponder = [self __my__becomeFirstResponder];
    if ([self canBecomeFirstResponder]) {
        [MyKeyboard orderFront];
    }
    return becameFirstResponder;
}

+ (void)initialize
{
    Method old = class_getInstanceMethod(self, @selector(becomeFirstResponder));
    Method new = class_getInstanceMethod(self, @selector(__my__becomeFirstResponder));
    method_exchangeImplementations(old, new);
}
@end

Please don't use anything like this in any production code. Also, I haven't actually tested this, so YMMV.

ianh
An interesting idea, thanks I'll give it a try.
vickirk
+4  A: 

Here's an idea: modify the existing keyboard to your own needs. First, register to be notified when it appears on screen:

[[NSNotificationCenter defaultCenter] addObserver:self 
                                      selector:@selector(modifyKeyboard:)
                                      name:UIKeyboardWillShowNotification
                                      object:nil];

Then, in your modifyKeyboard method:

- (void)modifyKeyboard:(NSNotification *)notification 
{
    UIView *firstResponder = [[[UIApplication sharedApplication] keyWindow] performSelector:@selector(firstResponder)];

    for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows])
     for (UIView *keyboard in [keyboardWindow subviews])
      if([[keyboard description] hasPrefix:@"<UIKeyboard"] == YES)
      {
                MyFancyKeyboardView *customKeyboard = [[MyFancyKeyboardView alloc] initWithFrame: CGRectMake(0, 0, keyboard.frame.size.width, keyboard.frame.size.height);
                [keyboard addSubview: customKeyboard];
                [customKeyboard release];
            }
}

This adds your view on top of the original keyboard, so make sure you make it opaque.

luvieere
Another interesting idea, thanks I'll give this a try too, thanks.
vickirk
+4  A: 

What makes any of you guys think that a custom keyboard will cause Apple to reject your App, or will cause your customers to rate your App poorly?

Have you looked at any of the calculator utility Apps? Virtually every one of them implements a new keyboard in support of their App.

What about the money management Apps? They add keyboards with numbers and a decimal point - a missing standard keyboard in the Apple lineup.

A properly implemented non-standard keyboard will not get you App rejected, nor will it cause your customers to give you a poor review.

If you add a subview to an existing keyboard in order to try to add functionality - you risk having your App rejected. Apple recommends you NOT add a subview to their existing keyboards since these are likely to change in the future.

I wish there were a tutorial on how to build and implement a new keyboard since I'm struggling with that now myself - but it's simply because I am new to iPhone programming that it's taking me longer than it should to implement.

-t

Tim
A: 

Following this method, I now find that the iOS4 is different. It will not work. I am sure this is due to differences in naming subviews (or the sort). Does anyone know how to get around this same problem, for the iphone SDK 4?