1

enter image description here

Since standard Number Pad keyboard has "empty" button, but doesn't have "+/-" button, I decided to create my own Keyboard Extension. I've done it. enter image description here

But I don't know how to link (and invoke) it with a particular Text Field while other Text Fields using usual keyboards. Is there any opportunity to apply custom keyboardType like my own custom Keyboard?

Alex Pilugin
  • 683
  • 2
  • 10
  • 38
  • Hi David Seek! Have a look on my last answer. I used solution with KeyboardDelegate protocol (I published my all relevant code below). I think Apple could implement such a keyboard as a default choice as well. – Alex Pilugin Oct 10 '16 at 14:59
  • ah i see. allright! i was just going through my open answers and see if there is anything i can do. i was just curious because this question is still open as unanswered and unvoted. i'll just upvote your answer still you have been able to solve it yourself! have a good one buddy – David Seek Oct 10 '16 at 15:04

2 Answers2

1

I found solution based on simular question: How to input text using the buttons of an in-app custom keyboard

import UIKit

protocol KeyboardDelegate: class {
    func keyWasTapped(text: String)
}

class KeyboardView: 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 = "KeyboardView" // xib extention not included
        let view = Bundle.main.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(text: sender.titleLabel!.text!) // could alternatively send a tag value
    }

}

/* when error: "Could not load NIB in bundle" Could not load NIB in bundle Visit the properties of the .xib files in the file inspector ,the property "Target Membership" pitch on the select box ,then your xib file was linked with your target */

In main ViewController.swift

import UIKit

class ViewController: UIViewController, UITextFieldDelegate, KeyboardDelegate {

    @IBOutlet weak var text1: UITextField!
    @IBOutlet weak var text2: UITextField!


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        // initialize custom keyboard
        let keyboardView = KeyboardView(frame: CGRect(x: 0, y: 0, width: 375, height: 165))
        keyboardView.delegate = self // the view controller will be notified by the keyboard whenever a key is tapped

        // replace system keyboard with custom keyboard
        text1.inputView = keyboardView //accessoryView
        text1.delegate = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // required method for keyboard delegate protocol
    func keyWasTapped(text character: String) {

        if Int(character) != nil{
            text1.insertText(character)
        }

        if character == "⌫" {
            if !(text1.text?.isEmpty)! {
                let beforeText = text1.text!
                let truncated = beforeText.substring(to: beforeText.index(before: beforeText.endIndex))
                text1.text = truncated

            }
        }

        if character == "±" {
            let beforeText = text1.text!
            if var number = Int(beforeText) {
                number = -number
                text1.text = "\(number)"
            }
        }


    }

    func textFieldDidBeginEditing(_ textField: UITextField) {
        /*
        if (textField == self.text1) {
            //textField.inputView = keyboardView
        }
        */
    }

}

enter image description here

Community
  • 1
  • 1
Alex Pilugin
  • 683
  • 2
  • 10
  • 38
0

I have coded a calculator for metric/imperial system. For that, I have coded my own keyboard, too.

enter image description here

I have set up the keyboard as UIButtons stacked within a Stack View.

enter image description here

The Buttons seem to be unknown for Xcode since I have just upgraded to Xcode 8 and the project is still in Swift 2.2.

enter image description here

Then I have set a UITextField and filled its text property using my buttons. This is for example the function for the Button 1 on my keyboard.

@IBOutlet weak var inputField: UITextField!
var numberStr:String = "0"
inputField.text = numberStr

@IBAction func oneKeyboardAction(sender: AnyObject) {
    if numberStr == "0" {
        numberStr = String(numberStr.characters.dropLast())
    }
    let newStr:String = numberStr + String("1")
    numberStr = newStr
    let dotToCommaString = newStr.stringByReplacingOccurrencesOfString(".", withString: ",")
    inputField.text = dotToCommaString
}

Also I have deactivated user interaction with the TextField, so the "original Keyboard" will not show.

Edit

Like mentioned in the comment section and to have my answer better fit your needs. You could set my custom keyboard into a UIView overlapping your UIViewController inside the Interface Builder. Set it as MyKeyboardView.hidden = true inside the viewDidLoad().

Then you have your TextField where you want the custom Keyboard to be visible instead of the system one:

func textFieldDidBeginEditing(_ textField: UITextField) {
    if (textField == self.yourDesiredTextField) { //the one where you want to use the custom keyboard 
        MyKeyboardView.hidden = false
    }
}

Then you add a gesture recognizer like that:

override func viewDidLoad() {
        super.viewDidLoad()

        MyKeyboardView.hidden = true


        let tap = UITapGestureRecognizer(target: self, action: #selector(gesture))
        tap.numberOfTapsRequired = 1
        view.addGestureRecognizer(tap)
}

func gesture() {

        UIView.animateWithDuration(0.2) {
            self.MyKeyboardView.hidden = true
        }

}

To have it little more smooth, I have added animateWithDuration when hiding the keyboard.

David Seek
  • 16,783
  • 19
  • 105
  • 136
  • I understand your solution but one question: Can you hide your set of buttons (as a Keyboard) when tap anywhere: override func viewDidLoad() { super.viewDidLoad() self.hideKeyboardWhenTappedAround() } – Alex Pilugin Sep 24 '16 at 15:24
  • my keyboard can't be hidden like that since it's fixed part of the uiviewcontroller. but you could put it into a UIView and hide this view, even animated, by setting a gesture recognizer. no problem at all – David Seek Sep 24 '16 at 15:27
  • my keyboard is set to be constant visible. like a hardware calculator, you know. but like said. put it into a UIView instead. hide it by default like `MyKeyboardView.hidden = true` and unhide it by func `textFieldDidBeginEditing(_ textField: UITextField) {MyKeyboardView.hidden = false}` and hide it again using a gesture recognizer – David Seek Sep 24 '16 at 15:29
  • I my case I need to hide and show different keyboards: My own number keyboard (with "+/-") for a Text Field and a ASCII capable keyboard for a Text View. – Alex Pilugin Sep 24 '16 at 15:30
  • no problem, i'll edit my answer to give you a better idea – David Seek Sep 24 '16 at 15:31
  • By the way, I created my custom Keyboard based on this nice tutorial: https://youtu.be/Bd-YqXsJrSk – Alex Pilugin Sep 24 '16 at 15:36