Create a custom in-app keyboard

suggest change

This is a basic in-app keyboard. The same method could be used to make just about any keyboard layout. Here are the main things that need to be done:

Create the .xib keyboard layout file

Create the .swift UIView subclass keyboard file

import UIKit

// The view controller will adopt this protocol (delegate)
// and thus must contain the keyWasTapped method
protocol KeyboardDelegate: class {
    func keyWasTapped(character: String)
}

class Keyboard: UIView {

    // This variable will be set as the view controller so that 
    // the keyboard can send messages to the view controller.
    weak var delegate: KeyboardDelegate?

    // MARK:- keyboard initialization

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        initializeSubviews()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        initializeSubviews()
    }

    func initializeSubviews() {
        let xibFileName = "Keyboard" // xib extention not included
        let view = NSBundle.mainBundle().loadNibNamed(xibFileName, owner: self, options: nil)[0] as! UIView
        self.addSubview(view)
        view.frame = self.bounds
    }

    // MARK:- Button actions from .xib file

    @IBAction func keyTapped(sender: UIButton) {
        // When a button is tapped, send that information to the 
        // delegate (ie, the view controller)
        self.delegate?.keyWasTapped(sender.titleLabel!.text!) // could alternatively send a tag value
    }

}
**Keyboard.h File**

 #import <UIKit/UIKit.h>

 // The view controller will adopt this protocol (delegate)
 // and thus must contain the keyWasTapped method
 @protocol KeyboardDelegate<NSObject>
 - (void)keyWasTapped:(NSString *)character;
 @end

 @interface Keyboard : UIView
 @property (nonatomic, weak) id<KeyboardDelegate> delegate;  
 @end

Keyboard.m File

#import "Keyboard.h"

@implementation Keyboard

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    [self initializeSubviews];
    return self;
}

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    [self initializeSubviews];
    return self;
}

- (void)initializeSubviews {
    NSString *xibFileName = @"Keyboard"; // xib extention not included
    UIView *view = [[[NSBundle mainBundle] loadNibNamed:xibFileName owner:self options:nil] firstObject];
    [self addSubview:view];
    view.frame = self.bounds;
}

// MARK:- Button actions from .xib file

-(IBAction)keyTapped:(UIButton *)sender {
    // When a button is tapped, send that information to the
    // delegate (ie, the view controller)
    [self.delegate keyWasTapped:sender.titleLabel.text]; // could alternatively send a tag value
}

@end

Set up the View Controller

import UIKit

class ViewController: UIViewController, KeyboardDelegate {

    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // initialize custom keyboard
        let keyboardView = Keyboard(frame: CGRect(x: 0, y: 0, width: 0, height: 300))
        keyboardView.delegate = self // the view controller will be notified by the keyboard whenever a key is tapped
    
        // replace system keyboard with custom keyboard
        textField.inputView = keyboardView
    }

    // required method for keyboard delegate protocol
    func keyWasTapped(character: String) {
        textField.insertText(character)
    }
}

.h File

#import <UIKit/UIKit.h>

 @interface ViewController : UIViewController

 @end

.m File

#import "ViewController.h"
#import "Keyboard.h"

@interface ViewController ()<KeyboardDelegate>

@property (nonatomic, weak) IBOutlet UITextField *textField;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    // initialize custom keyboard
    Keyboard *keyboardView = [[Keyboard alloc] initWithFrame:CGRectMake(0, 0, 0, 300)];
    keyboardView.delegate = self; // the view controller will be notified by the keyboard whenever a key is tapped

    // replace system keyboard with custom keyboard
    self.textField.inputView = keyboardView;
}

- (void)keyWasTapped:(NSString *)character {
    [self.textField insertText:character];
}

@end

Common error

If you are getting an EXC_BAD_ACCESS error, it is probably because you set the view’s custom class as Keyboard rather than do this for the nib File’s Owner.

Select Keyboard.nib and then choose File’s Owner.

Make sure that the custom class for the root view is blank.

Notes

This example comes originally from this Stack Overflow answer.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


Managing the Keyboard:
* Create a custom in-app keyboard

Table Of Contents
4 Managing the Keyboard
12 UIView
15 UIColor
26 UIImage
28 CALayer
30 NSDate
40 iBeacon
49 NSTimer
79 NSURL
87 AWS SDK
96 NSData
101 Segues
104 EventKit
105 NSBundle
106 SiriKit
111 StoreKit
117 3D Touch
119 Keychain
122 Block
141 AirDrop
144 UISlider
145 Carthage
146 HealthKit
151 plist
157 MVVM
164 UIPhoenix
166 Simulator
168 NSArray
169 OpenGL
175 Core Data
179 MyLayout
180 UIFont
189 Security
200 Codable