Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 8 Custom Keyboard: Changing the Height

I have tried to create a custom keyboard in iOS 8 that replaces the stock one. I really searched and could not find out if it is possible to create a keyboard with more height than the stock iOS keyboard. I replaced UIInputView but could never manage to change the height available to me.

like image 471
sdtaheri Avatar asked Jun 11 '14 16:06

sdtaheri


1 Answers

This is my code on Xcode 6.0 GM. Both orientations are supported.

Update: Thanks to @SoftDesigner, we can eliminate the constraint conflict warning now.

Warning: XIB and storyboard are not tested. It's been reported by some folks that this does NOT work with XIB.

KeyboardViewController.h

#import <UIKit/UIKit.h>  @interface KeyboardViewController : UIInputViewController  @property (nonatomic) CGFloat portraitHeight; @property (nonatomic) CGFloat landscapeHeight; @property (nonatomic) BOOL isLandscape; @property (nonatomic) NSLayoutConstraint *heightConstraint; @property (nonatomic) UIButton *nextKeyboardButton;  @end 

KeyboardViewController.m

#import "KeyboardViewController.h"  @interface KeyboardViewController () @end  @implementation KeyboardViewController  - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];     if (self) {         // Perform custom initialization work here         self.portraitHeight = 256;         self.landscapeHeight = 203;     }     return self; }  - (void)updateViewConstraints {     [super updateViewConstraints];     // Add custom view sizing constraints here     if (self.view.frame.size.width == 0 || self.view.frame.size.height == 0)         return;      [self.inputView removeConstraint:self.heightConstraint];     CGSize screenSize = [[UIScreen mainScreen] bounds].size;     CGFloat screenH = screenSize.height;     CGFloat screenW = screenSize.width;     BOOL isLandscape =  !(self.view.frame.size.width ==                       (screenW*(screenW<screenH))+(screenH*(screenW>screenH)));     NSLog(isLandscape ? @"Screen: Landscape" : @"Screen: Potriaint");     self.isLandscape = isLandscape;     if (isLandscape) {         self.heightConstraint.constant = self.landscapeHeight;         [self.inputView addConstraint:self.heightConstraint];     } else {         self.heightConstraint.constant = self.portraitHeight;         [self.inputView addConstraint:self.heightConstraint];     } }  - (void)viewWillAppear:(BOOL)animated {     [super viewWillAppear:animated]; }  - (void)viewDidLoad {     [super viewDidLoad];      // Perform custom UI setup here     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]];       self.heightConstraint = [NSLayoutConstraint constraintWithItem:self.inputView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:self.portraitHeight];      self.heightConstraint.priority = UILayoutPriorityRequired - 1; // This will eliminate the constraint conflict warning.  }  - (void)textWillChange:(id<UITextInput>)textInput {     // The app is about to change the document's contents. Perform any preparation here. }  - (void)textDidChange:(id<UITextInput>)textInput { }  @end 

Swift 1.0 version:

class KeyboardViewController: UIInputViewController {      @IBOutlet var nextKeyboardButton: UIButton!      let portraitHeight:CGFloat = 256.0     let landscapeHeight:CGFloat = 203.0     var heightConstraint: NSLayoutConstraint?     override func updateViewConstraints() {         super.updateViewConstraints()         // Add custom view sizing constraints here         if (self.view.frame.size.width == 0 || self.view.frame.size.height == 0) {             return         }         inputView.removeConstraint(heightConstraint!)         let screenSize = UIScreen.mainScreen().bounds.size         let screenH = screenSize.height;         let screenW = screenSize.width;         let isLandscape =  !(self.view.frame.size.width == screenW * ((screenW < screenH) ? 1 : 0) + screenH * ((screenW > screenH) ? 1 : 0))         NSLog(isLandscape ? "Screen: Landscape" : "Screen: Potriaint");         if (isLandscape) {             heightConstraint!.constant = landscapeHeight;             inputView.addConstraint(heightConstraint!)         } else {             heightConstraint!.constant = self.portraitHeight;             inputView.addConstraint(heightConstraint!)         }     }      override func viewDidLoad() {         super.viewDidLoad()          // Perform custom UI setup here         self.nextKeyboardButton = UIButton.buttonWithType(.System) as UIButton          self.nextKeyboardButton.setTitle(NSLocalizedString("Next Keyboard", comment: "Title for 'Next Keyboard' button"), forState: .Normal)         self.nextKeyboardButton.sizeToFit()     self.nextKeyboardButton.setTranslatesAutoresizingMaskIntoConstraints(false)          self.nextKeyboardButton.addTarget(self, action: "advanceToNextInputMode", forControlEvents: .TouchUpInside)          self.view.addSubview(self.nextKeyboardButton)          var nextKeyboardButtonLeftSideConstraint = NSLayoutConstraint(item: self.nextKeyboardButton, attribute: .Left, relatedBy: .Equal, toItem: self.view, attribute: .Left, multiplier: 1.0, constant: 0.0)         var nextKeyboardButtonBottomConstraint = NSLayoutConstraint(item: self.nextKeyboardButton, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1.0, constant: 0.0)         self.view.addConstraints([nextKeyboardButtonLeftSideConstraint, nextKeyboardButtonBottomConstraint])          heightConstraint = NSLayoutConstraint(item: self.inputView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: portraitHeight)         heightConstraint!.priority = 999.0     }      override func textWillChange(textInput: UITextInput) {         // The app is about to change the document's contents. Perform any preparation here.     }      override func textDidChange(textInput: UITextInput) {         // The app has just changed the document's contents, the document context has been updated.          var textColor: UIColor         var proxy = self.textDocumentProxy as UITextDocumentProxy         if proxy.keyboardAppearance == UIKeyboardAppearance.Dark {             textColor = UIColor.whiteColor()         } else {             textColor = UIColor.blackColor()         }         self.nextKeyboardButton.setTitleColor(textColor, forState: .Normal)     } } 
like image 57
skyline75489 Avatar answered Sep 27 '22 21:09

skyline75489