How to input text using the buttons of an in-app custom keyboard

后端 未结 2 649
刺人心
刺人心 2021-01-17 23:53

I\'ve made an in-app custom keyboard that replaces the system keyboard and pops up when I tap inside a UITextField.

Here is my code:



        
相关标签:
2条回答
  • 2021-01-18 00:26

    I imagine something like this:

    A new function to handle button event

    func updateTextfield(sender: UIButton) {
        textField.text = (textField.text ?? "") + (sender.titleForState(.Normal) ?? "")
    }
    

    And after init your custom keyboard, register the buttons:

    myCustomKeyboard.subviews
        .filter { $0 as? UIButton != nil } // Keep the buttons only
        .forEach { ($0 as! UIButton).addTarget(self, action: "updateTextfield", forControlEvents: .TouchUpInside)}
    
    0 讨论(0)
  • 2021-01-18 00:49

    Setup

    • Make an xib file that includes all your keys
    • Use Autolayout so that the keys will resize to the correct proportions no matter how big the keyboard is set to later.
    • Create a swift file with the same name as the xib file and set it as the file owner in the xib file setting.

    • Hook up all the key buttons to an IBAction method in the swift file. (See the code below.)

    Code

    I'm using the delegate pattern to communicate between the custom keyboard view and the main view controller. This allows them to be decoupled. Multiple different custom keyboards could be swapped in and out without needing to change the detailed implementation code in the main view controller.

    Keyboard.swift file

    import UIKit
    
    protocol KeyboardDelegate {
        func keyWasTapped(character: String)
    }
    
    class Keyboard: UIView {
    
        var delegate: KeyboardDelegate?
    
        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 needed
            let view = NSBundle.mainBundle().loadNibNamed(xibFileName, owner: self, options: nil)[0] as! UIView
            self.addSubview(view)
            view.frame = self.bounds
        }
    
        @IBAction func keyTapped(sender: UIButton) {
            self.delegate?.keyWasTapped(sender.titleLabel!.text!)
        }
    
    }
    

    Main view controller

    Note that the ViewController conforms to the KeyboardDelegate protocol that we created. Also, when creating an instance of the keyboard view, the height needs to be set but the width doesn't. Apparently setting the inputView of the text field updates the keyboard view width to the screen width, which is convenient.

    class ViewController: UIViewController, KeyboardDelegate {
    
        @IBOutlet weak var textField: UITextField!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // get an instance of the Keyboard (only the height is important)
            let keyboardView = Keyboard(frame: CGRect(x: 0, y: 0, width: 0, height: 300))
    
            // use the delegate to communicate
            keyboardView.delegate = self
    
            // replace the system keyboard with the custom keyboard
            textField.inputView = keyboardView
        }
    
        // required method for keyboard delegate protocol
        func keyWasTapped(character: String) {
            textField.insertText(character)
        }
    
    }
    

    Sources

    • The suggestions in @ryancrunchi's comment were helpful.
    • This answer from Creating a reusable UIView with xib (and loading from storyboard)

    Related

    • A Swift example of Custom Views for Data Input (custom in-app keyboard)
    0 讨论(0)
提交回复
热议问题