Swift自定义数字键盘

2020-06-24  本文已影响0人  玉思盈蝶

效果如下:

image.png
import UIKit

protocol KeyboardViewDelegate: NSObjectProtocol{
    
    func keyboardView(_ view: KeyboardView, didPressNumberButton button: UIButton, number: Int)
    func keyboardView(_ view: KeyboardView, didPressDeleteButton button: UIButton)
    func keyboardView(_ view: KeyboardView, didLongPressDeleteButton button: UIButton)
    func keyboardView(_ view: KeyboardView, didPressDotButton button: UIButton)
    func keyboardView(_ view: KeyboardView, didPressHyphenButton button: UIButton)
}

extension KeyboardViewDelegate {
    
    func keyboardView(_ view: KeyboardView, didPressNumberButton button: UIButton, number: Int) {
        print("did press \(number)")
    }
    
    func keyboardView(_ view: KeyboardView, didPressDeleteButton button: UIButton) {
        print("did press delete")
    }
    func keyboardView(_ view: KeyboardView, didLongPressDeleteButton button: UIButton) {
        print("did press long delete")
    }
    func keyboardView(_ view: KeyboardView, didPressDotButton button: UIButton) {
        print("did press dot")
    }
    
    func keyboardView(_ view: KeyboardView, didPressHyphenButton button: UIButton) {
        print("did press -")
    }
}

protocol KeyboardTextFieldProtocol {
    func customize(textField: UITextField)
}

extension KeyboardTextFieldProtocol {
    func customize(textField: UITextField) {
        textField.inputView = UIView.init(frame: CGRect.zero)
        textField.inputAccessoryView = UIView.init(frame: CGRect.zero)
        let item: UITextInputAssistantItem = textField.inputAssistantItem
        item.leadingBarButtonGroups = []
        item.trailingBarButtonGroups = []
    }
}

class KeyboardView: UIView {

    enum KeyboardViewType {
        case normal
        case withDot
    }
    
    var type: KeyboardViewType = .normal
    weak var delegate: KeyboardViewDelegate?
    
    // MARK: - Property
    private var baseView: UIView?
    
    // MARK: - Life cycle
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    convenience init(type: KeyboardViewType = KeyboardViewType.normal){
        self.init(frame: CGRect.zero)
        self.type = type
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    
    override func didMoveToSuperview() {
        super.didMoveToSuperview()
        makeViews()
        makeFrames()
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        baseView?.frame = self.bounds
    }
    
    // MARK: - Make Views
    private func makeViews(){
         baseView = self.makeBaseViews()
         self.addSubview(baseView!)
    }
    
    private func makeBaseViews() -> UIView{
        let view = UIView()
        view.backgroundColor = UIColor(hexString: "C6C9D0")
        view.layer.cornerRadius = 4
        view.clipsToBounds = true
        let range = 0...11

        for index in range
        {
            let button = makeNumberButton(index:index)
            button.tag = index
            view.addSubview(button)
        }
        
        return view
    }
    
    private func makeNumberButton(index: Int) -> UIButton{
        let button = UIButton()
        if index < 9 {
            button.setAttributedTitle(NSAttributedString.init(string: "\(index + 1)", attributes: [NSAttributedString.Key.font:UIFont.systemFont(ofSize: 27)]), for: .normal)
            button.setBackgroundImage(UIImage(named: "keyboard_number"), for: .normal)
        } else if 9 == index{
            button.setAttributedTitle(NSAttributedString.init(string: "0", attributes: [NSAttributedString.Key.font:UIFont.systemFont(ofSize: 27)]), for: .normal)
            button.setBackgroundImage(UIImage(named: "keyboard_number"), for: .normal)
        }else if 10 == index{
            switch self.type {
            case .normal:
                button.setAttributedTitle(NSAttributedString.init(string: "-", attributes: [NSAttributedString.Key.font:UIFont.systemFont(ofSize: 27)]), for: .normal)
                button.setBackgroundImage(UIImage(named: "keyboard_number"), for: .normal)
            case .withDot:
                button.setBackgroundImage(UIImage(named: "keyboard_dot"), for: .normal)
            }
        }else if 11 == index{
            button.setBackgroundImage(UIImage(named: "keyboard_delete"), for: .normal)
        }
        button.addTarget(self, action: #selector(KeyboardView.didPressButton(_:)), for: .touchUpInside)
        let longPress = UILongPressGestureRecognizer(target: self, action: #selector(KeyboardView.didLongPressButton(_:)))
        longPress.minimumPressDuration = 0.8
        button.addGestureRecognizer(longPress)
        
        button.tag = index
        return button
    }
    // MARK: - Make Frames
    private func makeFrames(){
        makeBaseViewFrames()
    }
    
    private func makeBaseViewFrames(){
        makeButtonFrames()
    }
    
    private func makeButtonFrames(){
        for item in baseView!.subviews {
            let itemIndex = item.tag
            if  itemIndex < 6{
                item.frame = CGRect(x: 10 + itemIndex * (81 + 12), y: 10, width: 81, height: 76)
            }else if 6 <= itemIndex && itemIndex <= 11 {
                item.frame = CGRect(x: 10 + (itemIndex - 6) * (81 + 12), y: 96, width: 81, height: 76)
            }
        }
    }
    
    // MARK: - Actions
    @objc private func didPressButton(_ sender:UIButton){
        let index = sender.tag
        if index < 9 {
            delegate?.keyboardView(self, didPressNumberButton: sender, number: index + 1)
        }else if 9 == index{
            delegate?.keyboardView(self, didPressNumberButton: sender, number: 0)
        }else if 10 == index{
            switch self.type {
            case .normal:
                delegate?.keyboardView(self, didPressHyphenButton: sender)
            case .withDot:
                delegate?.keyboardView(self, didPressDotButton: sender)
            }
        }else if 11 == index{
            delegate?.keyboardView(self, didPressDeleteButton: sender)
        }
    }
    
    @objc private func didLongPressButton(_ press:UILongPressGestureRecognizer){
        guard let sender = press.view as? UIButton else { return }
        if 11 == sender.tag {
            delegate?.keyboardView(self, didLongPressDeleteButton: sender)
        }
    }
}

使用如下:

private lazy var keyBoard: KeyboardView = {
    let temp = KeyboardView(frame: CGRect(x: (screenW - 565)/2.0, y: 400, width: 565, height: 180))
    temp.type = .withDot
    return temp
}()

实现代理,处理输入数据:

extension ViewController: KeyboardViewDelegate
{
    func keyboardView(_ view: KeyboardView, didPressNumberButton button: UIButton, number: Int) {
        if textField.isFirstResponder{
            if let existString = textField.text{
                let array = existString.components(separatedBy: ".")
                if array.count >= 2 && array[1].count >= 2{
                    return //如果小数点后已经有2位了就不可以在输入了
                }
                textField.text = existString + "\(number)"
            }
        }
    }
    
    func keyboardView(_ view: KeyboardView, didPressDeleteButton button: UIButton) {
        if textField.isFirstResponder{
            if let existString = textField.text{
                if !existString.isEmpty {
                    textField.text = String(existString.dropLast())
                }
            }
        }
    }
    
    func keyboardView(_ view: KeyboardView, didLongPressDeleteButton button: UIButton) {
        if textField.isFirstResponder{
            if let existString = textField.text{
                if !existString.isEmpty {
                    textField.text = ""
                }
            }
        }
    }
    
    func keyboardView(_ view:KeyboardView, didPressDotButton button:UIButton){
        if textField.isFirstResponder{
            if let existString = textField.text{
                guard !existString.contains(".") else {//已经有小数点了就不可以再有了
                    return
                }
                if !existString.isEmpty {
                    textField.text = existString + "."
                }
            }
        }
    }
}

PS:

1、type控制键盘类型是带.的还是-的;
2、代理实现对textField的特殊处理;
3、有个疑问:iPad上的数字键盘和iPhone上的数字键盘不一样。

代码如下:

let textField: UITextField = UITextField(frame: CGRect(x: 100, y: 400, width: 200, height: 50))
textField.keyboardType = .decimalPad
textField.backgroundColor = UIColor.green
self.view.addSubview(textField)
iPhone上显示如下:
image.png
iPad上显示如下:
image.png

话说你们都是怎么处理iPad上的数字键盘的呢?

上一篇下一篇

猜你喜欢

热点阅读