When Making a Custom iOS Keyboard Extension, How to Create a Button That Has the Same Functionality as Apple's Original Backspace Key

When making a custom iOS keyboard extension, how can I create a button that has the same functionality as Apple's original backspace key?

I Found the answer from HERE.

In this keyBoard the deleteButton have same functionality as I want.

Code for that button is:

private func addDeleteButton() {
deleteButton = KeyButton(frame: CGRectMake(keyWidth * 8.5 + spacing * 9.5, keyHeight * 2.0 + spacing * 3.0 + predictiveTextBoxHeight, keyWidth * 1.5, keyHeight))
deleteButton.setTitle("\u{0000232B}", forState: .Normal)
deleteButton.addTarget(self, action: "deleteButtonPressed:", forControlEvents: .TouchUpInside)
self.view.addSubview(deleteButton)

let deleteButtonLongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "handleLongPressForDeleteButtonWithGestureRecognizer:")
deleteButton.addGestureRecognizer(deleteButtonLongPressGestureRecognizer)

let deleteButtonSwipeLeftGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "handleSwipeLeftForDeleteButtonWithGestureRecognizer:")
deleteButtonSwipeLeftGestureRecognizer.direction = .Left
deleteButton.addGestureRecognizer(deleteButtonSwipeLeftGestureRecognizer)
}

func deleteButtonPressed(sender: KeyButton) {
switch proxy.documentContextBeforeInput {
case let s where s?.hasSuffix(" ") == true: // Cursor in front of tab, so delete tab.
for i in 0..<4 { // TODO: Update to use tab setting.
proxy.deleteBackward()
}
default:
proxy.deleteBackward()
}
updateSuggestions()
}

func handleLongPressForDeleteButtonWithGestureRecognizer(gestureRecognizer: UILongPressGestureRecognizer) {
switch gestureRecognizer.state {
case .Began:
if deleteButtonTimer == nil {
deleteButtonTimer = NSTimer(timeInterval: 0.1, target: self, selector: "handleDeleteButtonTimerTick:", userInfo: nil, repeats: true)
deleteButtonTimer!.tolerance = 0.01
NSRunLoop.mainRunLoop().addTimer(deleteButtonTimer!, forMode: NSDefaultRunLoopMode)
}
default:
deleteButtonTimer?.invalidate()
deleteButtonTimer = nil
updateSuggestions()
}
}

func handleSwipeLeftForDeleteButtonWithGestureRecognizer(gestureRecognizer: UISwipeGestureRecognizer) {
// TODO: Figure out an implementation that doesn't use bridgeToObjectiveC, in case of funny unicode characters.
if let documentContextBeforeInput = proxy.documentContextBeforeInput as NSString? {
if documentContextBeforeInput.length > 0 {
var charactersToDelete = 0
switch documentContextBeforeInput {
case let s where NSCharacterSet.letterCharacterSet().characterIsMember(s.characterAtIndex(s.length - 1)): // Cursor in front of letter, so delete up to first non-letter character.
let range = documentContextBeforeInput.rangeOfCharacterFromSet(NSCharacterSet.letterCharacterSet().invertedSet, options: .BackwardsSearch)
if range.location != NSNotFound {
charactersToDelete = documentContextBeforeInput.length - range.location - 1
} else {
charactersToDelete = documentContextBeforeInput.length
}
case let s where s.hasSuffix(" "): // Cursor in front of whitespace, so delete up to first non-whitespace character.
let range = documentContextBeforeInput.rangeOfCharacterFromSet(NSCharacterSet.whitespaceCharacterSet().invertedSet, options: .BackwardsSearch)
if range.location != NSNotFound {
charactersToDelete = documentContextBeforeInput.length - range.location - 1
} else {
charactersToDelete = documentContextBeforeInput.length
}
default: // Just delete last character.
charactersToDelete = 1
}

for i in 0..<charactersToDelete {
proxy.deleteBackward()
}
}
}
updateSuggestions()
}

How to implement a fully functional backspace key in custom keyboard button swift

I was struggling with this for a while so thought i would answer the question. The following code responds to a custom backspace key being pressed on a uikeyboard that is a first responder to a UITextfield:

// the tag for the backspace button
if tag == "<"{
//the range of the selected text (handles multiple highlighted characters of a uitextfield)
let range = textField.selectedTextRange?;

// if the range is empty indicating the cursor position is
// singular (no multiple characters are highlighted) then delete the character
// in the position before the cursor
if range!.empty {

let start = textField.positionFromPosition(range!.start, offset: -1);
let end = axiomBuilderTV.positionFromPosition(range!.end, offset: 0);
axiomBuilderTV.replaceRange(axiomBuilderTV.textRangeFromPosition(start, toPosition: end), withText: "");
}
// multiple characters have been highlighted so remove them all
else {
textField.replaceRange(range!, withText: "");
}

}

How do I retrieve keystrokes from a custom keyboard on an iOS app?

Here's my custom keyboard which I believe addresses these as completely as 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 objective-Class (for the .h & .m files) based on UIView and a User Interface View file (for the .xib file). Make sure all three files have the same name. Using the Identity Inspector, make sure to set the XIB's File's Owner Custom Class to match the new object's name. Using the Attributes Inspector, set the form's size to Freeform and set the Status Bar to none. Using the Size Inspector, set the form's size, which should match the width of the standard keyboard (320 for iPhone portrait and 480 for iPhone landscape), but you can choose any height you like.

The form is ready to be used. Add buttons and connect them to the dataPress, backPress and enterPress as appropriate. The initWithFrame: and loadWithNIB functions will do all the magic to allow you to use a keyboard designed in Interface Builder.

To use this keyboard with a UITextField myTextField, just add the following code to your viewDidLoad:

self.keyboard = [[PVKeyboard alloc]initWithFrame:CGRectMake(0,488,320,60)];
self.keyboard.textField = self.myTextField;

Because of some limitations, this keyboard isn't reusable, so you'll need one per field. I can almost make it reusable, but I'm just not feeling that clever. The keyboard is also limited to UITextFields, but that's mainly because of limitations in implementing the enter key functionality, which I'll explain below.

Here's the magic that should allow you to design a better keyboard than this starter framework...

I've implemented the only property of this keyboard, textField, using a discreet a discrete setter (setTextField) because:

  1. we need the UITextField object to handle the enter problem
  2. we need UITextField because it conforms to the UITextInput protocol which conforms to UIKeyInput, which does much of our heavy lifting
  3. it was a convenient place to set the UITextInput's inputView field to use this keyboard.

You'll notice a second private property named delegate, which essentially typecasts the UITextField pointer to a UITextInput pointer. I probably could have done this cast inline, but I sensed this might be useful as a function for future expansion, perhaps to include support for UITextView.

The function dataPress is what inserts text input the edited field using the insertText method of UIKeyInput. This seems to work in all versions back to iOS 4. For my keyboard, I'm simply using the label of each button, which is pretty normal. Use whatever NSStrings strike your fancy.

The function dataBack does the backspace and is a little more complicated. When the UIKeyInput deleteBackward works, it works wonderfully. And while the documentation says it works back to iOS 3.2, it seems to only work back to iOS 5.0, which is when UITextField (and UITextView) conformed to the UITextInput protocol. So prior to that, you're on your own. Since iOS 4 support is a concern to many, I've implemented a lame backspace which works on the UITextField directly. If not for this requirement, I could have made this keyboard work with UITextView. And this backspace isn't as general, only deleting the last character, while deleteBackward will work properly even if the user moves the cursor.

The function enterPress implements the enter key, but is a complete kludge because Apple doesn't seem to give a method for invoking the enter key. So enterPress simply calls the UITextField's delegate function textFieldShouldReturn:, which most programmers implement. Please note that the delegate here is the UITextFieldDelegate for the UITextField and NOT the delegate property for the keyboard itself.

This solution goes around the normal keyboard processing, which hardly matters in the case of UITextField, but makes this technique unusable with UITextView since there is now way to insert line breaks in the text being edited.

That's pretty much it. It took 24 hours of reading and cobbling to make this work. I hope it helps somebody.

How to create a custom iOS keyboard

I have solved my problem. I discovered this site

on StackOverflow that completely solved my issues. I was able to add customized keys to the keyboard, which was my primary issue.

I created a class called DigitButton.swift.

import UIKit

class DigitButton: UIButton {
var digit: Int = 0
}

class NumericKeyboard: UIView {
weak var target: (UIKeyInput & UITextInput)?
var useDecimalSeparator: Bool

lazy var parenthesis1: UIButton = {
let button = UIButton(type: .system)
let decimalSeparator = "("
button.setTitle(decimalSeparator, for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = decimalSeparator
button.addTarget(self, action: #selector(didTapParenthesis1(_:)), for: .touchUpInside)
return button
}()

lazy var squareroot: UIButton = {
let button = UIButton(type: .system)
let decimalSeparator = "√"
button.setTitle(decimalSeparator, for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = decimalSeparator
button.addTarget(self, action: #selector(didTapSquareRoot(_:)), for: .touchUpInside)
return button
}()

lazy var parenthesis2: UIButton = {
let button = UIButton(type: .system)
let decimalSeparator = ")"
button.setTitle(decimalSeparator, for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = decimalSeparator
button.addTarget(self, action: #selector(didTapParenthesis2), for: .touchUpInside)
return button
}()

lazy var exponentButton: UIButton = {
let button = UIButton(type: .system)
let decimalSeparator = "^0"
button.setTitle(decimalSeparator, for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = decimalSeparator
button.addTarget(self, action: #selector(didTapExponentButton(_:)), for: .touchUpInside)
return button
}()

lazy var exponentButton2: UIButton = {
let button = UIButton(type: .system)
let decimalSeparator = "^2"
button.setTitle(decimalSeparator, for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = decimalSeparator
button.addTarget(self, action: #selector(didTapExponentButton2(_:)), for: .touchUpInside)
return button
}()

lazy var exponentButton3: UIButton = {
let button = UIButton(type: .system)
let decimalSeparator = "^3"
button.setTitle(decimalSeparator, for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = decimalSeparator
button.addTarget(self, action: #selector(didTapExponentButton3(_:)), for: .touchUpInside)
return button
}()

lazy var exponentButton4: UIButton = {
let button = UIButton(type: .system)
let decimalSeparator = "^"
button.setTitle(decimalSeparator, for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = decimalSeparator
button.addTarget(self, action: #selector(didTapExponentButton4(_:)), for: .touchUpInside)
return button
}()

lazy var addButton: UIButton = {
let button = UIButton(type: .system)
let decimalSeparator = "+"
button.setTitle(decimalSeparator, for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = decimalSeparator
button.addTarget(self, action: #selector(didTapAddButton(_:)), for: .touchUpInside)
return button
}()

lazy var subtractButton: UIButton = {
let button = UIButton(type: .system)
let decimalSeparator = "-"
button.setTitle(decimalSeparator, for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = decimalSeparator
button.addTarget(self, action: #selector(didTapSubtractButton(_:)), for: .touchUpInside)
return button
}()

lazy var divideButton: UIButton = {
let button = UIButton(type: .system)
let decimalSeparator = "/"
button.setTitle(decimalSeparator, for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = decimalSeparator
button.addTarget(self, action: #selector(didTapDivideButton(_:)), for: .touchUpInside)
return button
}()


lazy var multiplyButton: UIButton = {
let button = UIButton(type: .system)
let decimalSeparator = "*"
button.setTitle(decimalSeparator, for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = decimalSeparator
button.addTarget(self, action: #selector(didTapMultiplyButton(_:)), for: .touchUpInside)
return button
}()



lazy var numericButtons: [DigitButton] = (0...9).map {
let button = DigitButton(type: .system)
button.digit = $0
button.setTitle("\($0)", for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .title1)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.sizeToFit()
button.titleLabel?.numberOfLines = 1
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.lineBreakMode = .byTruncatingTail
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.addTarget(self, action: #selector(didTapDigitButton(_:)), for: .touchUpInside)
button.inputView.self?.sizeToFit()
return button
}

var deleteButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("⌫", for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)

button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = "Delete"
button.addTarget(self, action: #selector(didTapDeleteButton(_:)), for: .touchUpInside)
return button
}()



init(target: UIKeyInput & UITextInput, useDecimalSeparator: Bool = false) {
self.target = target
self.useDecimalSeparator = useDecimalSeparator
super.init(frame: .zero)
configure()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

// MARK: - Actions

extension NumericKeyboard {

@objc func didTapSquareRoot(_ sender: DigitButton) {
insertText("√")
}

@objc func didTapParenthesis1(_ sender: DigitButton) {
insertText("(")
}

@objc func didTapParenthesis2(_ sender: DigitButton) {
insertText(")")
}
@objc func didTapDigitButton(_ sender: DigitButton) {
insertText("\(sender.digit)")
}

@objc func didTapDecimalButton(_ sender: DigitButton) {
insertText(Locale.current.decimalSeparator ?? ".")
}

@objc func didTapExponentButton(_ sender: DigitButton){
insertText("^0")
}

@objc func didTapExponentButton2(_ sender: DigitButton){
insertText("^2")
}

@objc func didTapExponentButton3(_ sender: DigitButton){
insertText("^3")
}

@objc func didTapExponentButton4(_ sender: DigitButton){
insertText("^")
}


@objc func didTapAddButton(_ sender: DigitButton){
insertText("+")
}


@objc func didTapSubtractButton(_ sender: DigitButton){
insertText("-")
}


@objc func didTapDivideButton(_ sender: DigitButton){
insertText("/")
}


@objc func didTapMultiplyButton(_ sender: DigitButton){
insertText("*")
}

@objc func didTapDeleteButton(_ sender: DigitButton) {
target?.deleteBackward()
}
}

// MARK: - Private initial configuration methods

private extension NumericKeyboard {
func configure() {
autoresizingMask = [.flexibleWidth, .flexibleHeight]
addButtons()
}

func addButtons() {
let stackView = createStackView(axis: .vertical)
stackView.frame = bounds
stackView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(stackView)

for row in 0 ..< 3 {
let subStackView = createStackView(axis: .horizontal)
stackView.addArrangedSubview(subStackView)

for column in 0 ..< 3 {
subStackView.addArrangedSubview(numericButtons[row * 3 + column + 1])
}
}

let subStackView = createStackView(axis: .horizontal)
stackView.addArrangedSubview(subStackView)

subStackView.addArrangedSubview(numericButtons[0])

subStackView.addArrangedSubview(parenthesis1)
subStackView.addArrangedSubview(parenthesis2)
subStackView.addArrangedSubview(squareroot)

subStackView.addArrangedSubview(addButton)
subStackView.addArrangedSubview(subtractButton)
subStackView.addArrangedSubview(multiplyButton)
subStackView.addArrangedSubview(divideButton)


subStackView.addArrangedSubview(exponentButton)
subStackView.addArrangedSubview(exponentButton2)
subStackView.addArrangedSubview(exponentButton4)

subStackView.addArrangedSubview(deleteButton)

}

func createStackView(axis: NSLayoutConstraint.Axis) -> UIStackView {
let stackView = UIStackView()
stackView.axis = axis
stackView.alignment = .fill
stackView.distribution = .fillProportionally
return stackView
}

func insertText(_ string: String) {
guard let range = target?.selectedRange else { return }

if let textField = target as? UITextField, textField.delegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) == false {
return
}

if let textView = target as? UITextView, textView.delegate?.textView?(textView, shouldChangeTextIn: range, replacementText: string) == false {
return
}

target?.insertText(string)
}
}

// MARK: - UITextInput extension

extension UITextInput {
var selectedRange: NSRange? {
guard let textRange = selectedTextRange else { return nil }

let location = offset(from: beginningOfDocument, to: textRange.start)
let length = offset(from: textRange.start, to: textRange.end)
return NSRange(location: location, length: length)
}
}

Then I set my InputView input method with textField.inputView = NumericKeyboard(target: textField)

This has worked perfectly.

iOS 8 Custom Keyboard: Changing the Height

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()


Related Topics



Leave a reply



Submit