Search code examples
iosiphonekeyboarduikit

How to hide the letters on a .numberPad keyboard?


By default, when using a .numberPad keyboard on iPhone, the number keys also feature letters at the bottom of each key.

enter image description here

The letters are purely cosmetic, to help people with number input; but in my case (entering item quantities), they’re completely superfluous, maybe even confusing.

Is it possible to configure the keyboard to hide these letters? Should I implement my own keyboard view just to properly present the keys?


Solution

  • I don’t believe there is currently a “digit only” keyboard without the text characters.

    But you can create your own:

    textField.inputView = NumericKeyboard(target: textField)
    

    Where

    class DigitButton: UIButton {
        var digit: Int = 0
    }
    
    class NumericKeyboard: UIView {
        weak var target: UIKeyInput?
    
        var numericButtons: [DigitButton] = (0...9).map {
            let button = DigitButton(type: .system)
            button.digit = $0
            button.setTitle("\($0)", for: .normal)
            button.titleLabel?.font = UIFont.preferredFont(forTextStyle: .largeTitle)
            button.setTitleColor(.black, for: .normal)
            button.layer.borderWidth = 0.5
            button.layer.borderColor = UIColor.darkGray.cgColor
            button.accessibilityTraits = [.keyboardKey]
            button.addTarget(self, action: #selector(didTapDigitButton(_:)), for: .touchUpInside)
            return button
        }
    
        var deleteButton: UIButton = {
            let button = UIButton(type: .system)
            button.setTitle("⌫", for: .normal)
            button.titleLabel?.font = UIFont.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) {
            self.target = target
            super.init(frame: .zero)
            configure()
        }
    
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    // MARK: - Actions
    
    extension NumericKeyboard {
        @objc func didTapDigitButton(_ sender: DigitButton) {
            target?.insertText("\(sender.digit)")
        }
    
        @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)
    
            let blank = UIView()
            blank.layer.borderWidth = 0.5
            blank.layer.borderColor = UIColor.darkGray.cgColor
    
            subStackView.addArrangedSubview(blank)
            subStackView.addArrangedSubview(numericButtons[0])
            subStackView.addArrangedSubview(deleteButton)
        }
    
        func createStackView(axis: NSLayoutConstraint.Axis) -> UIStackView {
            let stackView = UIStackView()
            stackView.axis = axis
            stackView.alignment = .fill
            stackView.distribution = .fillEqually
            return stackView
        }
    }
    

    That yields:

    enter image description here

    Clearly, you can go nuts, customizing your keyboard to look however you’d like to. The above is fairly primitive, something I just dashed together. But it illustrates the idea: Make you own input view and use the UIKeyInput protocol to communicate keyboard input to the control.