【问题标题】:How to make UIKeyboardType for hex input only?如何使 UIKeyboardType 仅用于十六进制输入?
【发布时间】:2018-03-16 16:56:59
【问题描述】:

是否有任何选项可以使用扩展名或任何其他方式快速创建仅具有 HEX(0-9,A,B,C,D,E,F) 值的新 UIKeyboardType ?我想要只启用十六进制字符的键盘,用户可以清楚地看到他只能输入十六进制字符,或者键盘上只能看到十六进制字符

【问题讨论】:

  • 只需制作包含用于输入 HEX 代码的按钮的 UIVIew,并将其传递给 UITextField 的 inputView 属性。
  • 很好,我试试这个
  • @VarunNaharia,迟到了,但我发布了一个使用 inputView 的示例,以防它有助于节省其他人的时间。

标签: ios swift uikeyboardtype


【解决方案1】:

按照 Saurabh Prajapati 的建议,以下代码创建一个十六进制键盘并将其传递给 inputView。

键盘是这样设计的:

设计基于 David Mulder 的布局 https://ux.stackexchange.com/a/58605/128044

HexadecimalKeyboard 类创建键盘。

protocol RemoveKeyboardDelegate: class {
    func removeKeyboard()
}

class HexButton: UIButton {
    var hexCharacter: String = ""
}

class HexadecimalKeyboard: UIView {
    weak var target   : UIKeyInput?
    weak var delegate : RemoveKeyboardDelegate?
    
    var hexadecimalButtons: [HexButton] = ["0","7","8","9","4","5","6","1","2","3","A","B","C","D","E","F"].map {
        let button = HexButton(type: .system)
        button.hexCharacter = $0
        button.setTitle("\($0)", for: .normal)
        button.backgroundColor = UIColor.secondarySystemGroupedBackground
        button.addTarget(self, action: #selector(didTapHexButton(_:)), for: .touchUpInside)
        return button
    }
    
    var deleteButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("⌫", for: .normal)
        button.backgroundColor = UIColor.systemGray4
        button.accessibilityLabel = "Delete"
        button.addTarget(self, action: #selector(didTapDeleteButton(_:)), for: .touchUpInside)
        return button
    }()
    
    var okButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("OK", for: .normal)
        button.backgroundColor = UIColor.systemGray4
        button.accessibilityLabel = "OK"
        button.addTarget(self, action: #selector(didTapOKButton(_:)), for: .touchUpInside)
        return button
    }()
    
    var mainStack: UIStackView = {
        let stackView = UIStackView()
        stackView.distribution = .fillEqually
        stackView.spacing      = 10
        stackView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        stackView.isLayoutMarginsRelativeArrangement = true
        stackView.layoutMargins = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        return stackView
    }()
    
    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 HexadecimalKeyboard {
    @objc func didTapHexButton(_ sender: HexButton) {
        target?.insertText("\(sender.hexCharacter)")
    }
    
    @objc func didTapDeleteButton(_ sender: HexButton) {
        target?.deleteBackward()
    }
    
    @objc func didTapOKButton(_ sender: HexButton) {
        delegate?.removeKeyboard()
    }
}


// MARK: - Private initial configuration methods

private extension HexadecimalKeyboard {
    func configure() {
        self.backgroundColor = .systemGroupedBackground
        autoresizingMask     = [.flexibleWidth, .flexibleHeight]
        buildKeyboard()
    }
    
    func buildKeyboard() {
        //MARK: - Add main stackview to keyboard
        mainStack.frame = bounds
        addSubview(mainStack)
        
        //MARK: - Create stackviews
        let panel1         = createStackView(axis: .vertical)
        let panel2         = createStackView(axis: .vertical)
        let panel2Group    = createStackView(axis: .vertical)
        let panel2Controls = createStackView(axis: .horizontal, distribution : .fillProportionally)
 
        
        //MARK: - Create multiple stackviews for numbers
        for row in 0 ..< 3 {
            let panel1Numbers = createStackView(axis: .horizontal)
            panel1.addArrangedSubview(panel1Numbers)
            
            for column in 0 ..< 3 {
                panel1Numbers.addArrangedSubview(hexadecimalButtons[row * 3 + column + 1])
            }
        }
        
        //MARK: - Create multiple stackviews for letters
        for row in 0 ..< 2 {
            let panel2Letters = createStackView(axis: .horizontal)
            panel2Group.addArrangedSubview(panel2Letters)
            
            for column in 0 ..< 3 {
                panel2Letters.addArrangedSubview(hexadecimalButtons[9 + row * 3 + column + 1])
            }
        }
        
        //MARK: - Nest stackviews
        mainStack.addArrangedSubview(panel1)
        panel1.addArrangedSubview(hexadecimalButtons[0])
        mainStack.addArrangedSubview(panel2)
        panel2.addArrangedSubview(panel2Group)
        panel2.addArrangedSubview(panel2Controls)
        panel2Controls.addArrangedSubview(deleteButton)
        panel2Controls.addArrangedSubview(okButton)
        
        //MARK: - Constraint - sets okButton width to two times the width of the deleteButton plus 10 points for the space
        panel2Controls.addConstraint(NSLayoutConstraint(
                                        item       : okButton,
                                        attribute  : .width,
                                        relatedBy  : .equal,
                                        toItem     : deleteButton,
                                        attribute  : .width,
                                        multiplier : 2,
                                        constant   : 10))
    }
    
    func createStackView(axis: NSLayoutConstraint.Axis, distribution: UIStackView.Distribution = .fillEqually) -> UIStackView {
        let stackView = UIStackView()
        stackView.axis         = axis
        stackView.distribution = distribution
        stackView.spacing      = 10
        return stackView
    }
}

代码来源于 Rob 提供的十进制键盘示例https://stackoverflow.com/a/57275689/1816667

下面是如何使用键盘的示例。在示例中,使用十六进制键盘设置了两个文本字段:

class ViewController: UIViewController {

    @IBOutlet var hexField: [UITextField]!
    
    override func viewDidLoad() {
        hexField[0].inputView  = HexadecimalKeyboard(target: hexField[0])
        hexField[1].inputView  = HexadecimalKeyboard(target: hexField[1])
    }
    
    @IBAction func clickTextField(_ sender: UITextField) {
        sender.reloadInputViews()
        sender.inputView  = HexadecimalKeyboard(target: sender)
        
        let hexadecimalKeyboard  = HexadecimalKeyboard(target: sender)
                sender.inputView = hexadecimalKeyboard
                hexadecimalKeyboard.delegate = self
    }
} // end of View Controller

extension ViewController: RemoveKeyboardDelegate {
    func removeKeyboard() {
        _ = hexField.map { $0.inputView?.removeFromSuperview() }
    }
}

此处提供了一个使用 Swift 5 的示例 Xcode 12 项目: https://github.com/PepperoniJoe/HexadecimalKeyboard

【讨论】:

    【解决方案2】:

    第一种情况,下面给出了键盘类型,我们可以设置textField.keyboardType属性并使用它。

    public enum UIKeyboardType : Int {    
        case `default` // Default type for the current input method.    
        case asciiCapable // Displays a keyboard which can enter ASCII characters    
        case numbersAndPunctuation // Numbers and assorted punctuation.    
        case URL // A type optimized for URL entry (shows . / .com prominently).    
        case numberPad // A number pad with locale-appropriate digits (0-9, ۰-۹, ०-९, etc.). Suitable for PIN entry.    
        case phonePad // A phone pad (1-9, *, 0, #, with letters under the numbers).    
        case namePhonePad // A type optimized for entering a person's name or phone number.
        case emailAddress // A type optimized for multiple email address entry (shows space @ . prominently).
        @available(iOS 4.1, *)
        case decimalPad // A number pad with a decimal point.
        @available(iOS 5.0, *)
        case twitter // A type optimized for twitter text entry (easy access to @ #)
        @available(iOS 7.0, *)
        case webSearch // A default keyboard type with URL-oriented addition (shows space . prominently).
        @available(iOS 10.0, *)
        case asciiCapableNumberPad // A number pad (0-9) that will always be ASCII digits.
        public static var alphabet: UIKeyboardType { get } // Deprecated
    }
    

    第二种情况是,您希望限制用户不要输入不需要的值(例如您只需要 1-9 和 az),在这种情况下您可以使用 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -&gt; Bool 委托并验证用户输入和输入字符根据您的要求返回true否则返回false

    第三种情况,如果可以选择使用给定键盘作为用户而不是更好地创建自定义键盘,请参阅Apple developer reference。还有nice tutorial我也学过。

    【讨论】:

    • 是的,我知道,但我只想知道是否可以扩展现有的键盘类型?
    • 也有一些方法可以创建自定义键盘,但如果你能清楚地解释你的要求,那就太好了。
    • 我想要只启用十六进制字符的键盘,用户可以清楚地看到他只能输入十六进制字符,或者键盘上只能看到十六进制字符
    • 正确,但作为用户,我可以将其切换回普通键盘吗?还是强制我只需要使用十六进制字符?
    猜你喜欢
    • 2020-10-15
    • 1970-01-01
    • 2011-02-15
    • 2014-11-04
    • 1970-01-01
    • 1970-01-01
    • 2014-03-19
    • 2021-11-01
    • 1970-01-01
    相关资源
    最近更新 更多