iOS 8 Custom Keyboards – In Two Steps

Making a custom keyboard in iOS 8 is extremely easy, if you think otherwise you’re a dinosaur! Currently, as of Xcode 6 Beta 6, there’s very little documentation and examples, but that doesn’t mean it’s hard. I spent the better half of an afternoon banging my head against a desk until I realized how simple it actually is. So as a part of my ongoing mission to do things the easy way (not pretending they’re difficult because I’m afraid of other people stealing my sweet app money) I present to you the “Create A Custom Keyboard In Two Steps” tutorial.

But first… I’m going to go over some important things to remember:

1. There’s no such thing as a free lunch! I naively assumed that I’d be able to piggy back on and fiddle around with existing native keyboard components. WRONG! You have to build absolutely everything yourself, from scratch. Brace yourself my friends for the onslaught of shitty, poorly designed keyboards.

2. Your keyboard cannot extend beyond the frame of the native keyboard space: 320×216 (non-retina). This means you cannot mimic the downstate overlay popup on the native keyboard for the top row of keys that pops up above the top of the keyboard. There’s nothing you can do about this, deal with it!

3. It must have a “next Keyboard” button, so the user can easily switch away from your shitty pink $3 emoji keyboard. Mark my words, they will be the new fart app.

4. Your keyboard can’t do anything beyond being a keyboard! It can’t replace text with images, it can’t trigger videos, it can’t clickjack, it can’t access the textField beyond sending text, and it can’t communicate with apps. IT’S A KEYBOARD! It sends unicode chars to a selected textField. That’s all it does.

OK, now that’s out of the way let’s get on with creating a custom keyboard in two easy steps:

Step 1.

Download the latest Xcode Beta from the Apple developer site. Install.

Step 2.

From the “File” menu, create a new target and select “Custom Keyboard”. Build this this target, and then switch back to the original project target run it, and in the SIMULATOR go to settings > general > keyboard > keyboards > Add New Keyboard and select your keyboard. That’s it! The mistake I originally made was trying to run the keyboard target that I’d made, not the original project, don’t do that, that’s stupid.

Ok I lied it’s not two steps, and it’s not really a keyboard, but I did tell you: There’s no such thing as a free lunch!

So we’ve got an empty view using the Xcode template that’s pretending to be a keyboard , here’s how you add a key to your keyboard in code:

So most of this should look like the viewDidLoad method in the template, except the part where we add a button and a target to hit a method.

 - (void)viewDidLoad {
    [super viewDidLoad];
  
// NEW STUFF
    UIButton *pressMeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [pressMeBtn setTitle:@"PRESS ME" forState:UIControlStateNormal];
    [pressMeBtn addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchDown];
    pressMeBtn.frame = CGRectMake(100, 100, 22, 22);
    [self.view addSubview: pressMeBtn];   
// END NEW STUFF

    self.nextKeyboardButton = [UIButton buttonWithType:UIButtonTypeSystem];
    
    [self.nextKeyboardButton setTitle:NSLocalizedString(@"Next Keyboard", @"Title for 'Next Keyboard' button") forState:UIControlStateNormal];
    [self.nextKeyboardButton sizeToFit];
    self.nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = NO;
    
    [self.nextKeyboardButton addTarget:self action:@selector(advanceToNextInputMode) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:self.nextKeyboardButton];
    
    NSLayoutConstraint *nextKeyboardButtonLeftSideConstraint = [NSLayoutConstraint constraintWithItem:self.nextKeyboardButton attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0];
    NSLayoutConstraint *nextKeyboardButtonBottomConstraint = [NSLayoutConstraint constraintWithItem:self.nextKeyboardButton attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
    [self.view addConstraints:@[nextKeyboardButtonLeftSideConstraint, nextKeyboardButtonBottomConstraint]];
}

The first time I tried this my biggest mistake was to try to add my views to the inputView not the actual view of the controller, don’t do that it’ll crash!

And then to actually cause the textfield to update with some text, insert text with the appropriately named insertText method:

- (void)buttonPressed:(UIButton *)sender
{
    [self.textDocumentProxy insertText:@"a"];
}

Go forth and unleash your crappy keyboard!

Leave a Reply

Your email address will not be published. Required fields are marked *