如何在 viewDidLoad 上的 Swift 中显示没有 UITextField 的标准数字键盘

How to show the standard number keyboard without a UITextField in Swift on viewDidLoad

我正在尝试在用户访问我的 ViewController 时显示标准的数字键盘,并且每次都能够捕获用户的输入以填充 UI 上的一些圆圈用户输入一个数字,有问题的圈子是我在 this question.

上显示的圈子

我该怎么做?我已经阅读过的所有问题都建议使用 UIKeyInput 协议来显示自定义键盘,但这不是我想要做的。其中之一是 this one.

我想出的代码,在检查了上面的 post 之后,就是这个,但是经过大量阅读和讨论,这是为了将上面的 UIView 作为我的自定义键盘我不确定如何做对。


ViewController

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var dotsView: DotsView!
    
    var keyInputView: KeyInputView = KeyInputView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        keyInputView.inputView = dotsView
        keyInputView.becomeFirstResponder()
        //self.view.addSubview(keyInputView) //In the XIB, the view is set to be displayed in center vertically and horizontally. If we uncomment this line, the view is pushed downwards.
    }
}

DotsView

import UIKit

class DotsView: UIView {
    @IBOutlet var contentView: UIView!
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet var digitDots: [CircleView]!
    
    //initWithFrame to init view from code
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }
      
    //initWithCode to init view from xib or storyboard
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupView()
    }
      
    //common func to init our view
    private func setupView() {
        Bundle.main.loadNibNamed("DotsView", owner: self, options: nil)
        addSubview(contentView)
        contentView.frame = self.bounds
        contentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
    }
}

CircleView

import UIKit

@IBDesignable
class CircleView: UIView {
    private var shapeLayer = CAShapeLayer()
    @IBInspectable var fillColor: UIColor = .blue {
        didSet {
            shapeLayer.fillColor = fillColor.cgColor
        }
    }

    override init(frame: CGRect = .zero) {
        super.init(frame: frame)

        configure()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        configure()
    }

    private func configure() {
        shapeLayer.fillColor = fillColor.cgColor
        layer.addSublayer(shapeLayer)
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        shapeLayer.path = UIBezierPath(ovalIn: bounds).cgPath
    }
}

KeyInputView

import UIKit

class KeyInputView: UIView {
   var _inputView: UIView?

   override var canBecomeFirstResponder: Bool { return true }
   override var canResignFirstResponder: Bool { return true }

   override var inputView: UIView? {
       set { _inputView = newValue }
       get { return _inputView }
   }
}

// MARK: - UIKeyInput
//Modify if need more functionality
extension KeyInputView: UIKeyInput {
    var hasText: Bool {
        return false
    }
    
    func insertText(_ text: String) {
        
    }
    
    func deleteBackward() {
        
    }
}

至于 XIB,您可以在 this repo

中访问它们

您可能想让您的 DotsView 符合 UIKeyInput...

class DotsView: UIView, UIKeyInput {
    
    @IBOutlet var contentView: UIView!
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet var digitDots: [CircleView]!
    
    //initWithFrame to init view from code
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }
      
    //initWithCode to init view from xib or storyboard
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupView()
    }
      
    //common func to init our view
    private func setupView() {
        Bundle.main.loadNibNamed("DotsView", owner: self, options: nil)
        addSubview(contentView)
        contentView.frame = self.bounds
        contentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
    }

    var keyboardType: UIKeyboardType {
        get {
            return .numberPad
        }
        set {}
    }

    // required by UIKeyInput protocol
    var hasText: Bool = false

    override var canBecomeFirstResponder: Bool {
        true
    }
    
    func insertText(_ text: String) {
        print("Number tapped:", text)
        // do something with the number that was tapped
    }
    
    func deleteBackward() {
        print("Delete Backward tapped")
        // do something because Delete was tapped
    }
}

然后将 ViewController 中的 viewDidLoad() 更改为:

override func viewDidLoad() {
    super.viewDidLoad()
    dotsView.becomeFirstResponder()
}

现在,您不需要额外的 KeyInputView