欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

IOS自定义键盘(swift/Objc)

程序员文章站 2022-05-31 17:16:49
...

效果图

IOS自定义键盘(swift/Objc)

自定义键盘的核心思想

  • 设置UITextFiled 的InputView
  • 切换键盘的思路为重新设置UITextFiled 的InputView然后再调用textFiled?.reloadInputViews()
    *剩下的就是按键的布局与代理设置了

swift版本采用策略模式实现,Objc版本使用常规模式实现

  • 策略模式请参看另一编文章https://blog.csdn.net/d06110902002/article/details/75642548

swift版本的策略模式实现的角色划分如下:

  • 策略管理类–键盘管理类KeyboardMgr
  • 通用策略类–键盘基类KeyboardBaseView
  • 具体的策略类–数字键盘、随机数字键盘、英文键盘
    ##具体的源码如下:
import UIKit

class KeyboardMgr: UIView {

    var keyboard : KeyboardBaseView?
    static let shareInstace = KeyboardMgr()
    
    lazy var keyboardInstanceDict : [String : KeyboardBaseView] = Dictionary()
    
    func setInputMethodKeyboard(keyboardview keyboard : KeyboardBaseView,
                                inputView textfiled:UITextField,
                                onKeyClickListener listener:OnKeyListener) {
        self.keyboard = keyboard
        self.keyboard?.createView(inputView: textfiled, addOnClickListener: listener)
        keyboardInstanceDict[keyboard.description] = keyboard
    }

}

  • 策略基类源码:
import UIKit

@objc protocol OnKeyListener {
    @objc optional func onClick(button view:UIButton);
    
    
    /// 文本观察监听接口
    /// - Parameters:
    ///   - view: 被观察的对象
    ///   - bStr: 观察之前的文本
    ///   - cStr: 当前u文本
    ///   - aStr: 编辑之后最终的文本
    @objc optional func addTextWatch(button view:UIButton,
                                     beforeText bStr:String?,
                                     curText cStr:String?,
                                     afterText aStr:String?);
    
}

class KeyboardBaseView: UIView {
    
    var textFiled       : UITextField?
    let DELETE          : NSInteger = 19;
    let FINISH          : NSInteger = 21;
    let ABC             : NSInteger = 22;
    let CAPTIAL         : NSInteger = 23;
    let SWITCH_TYPE     : NSInteger = 24;
    let SEARCH          : NSInteger = 25;
    let SPACE           : NSInteger = 98;
    
    
    var onClickListener : OnKeyListener?
    lazy var beforeText : String = String.init()
    lazy var curText    : String = String.init()
    lazy var afterText  : String = String.init()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    public func createView(inputView targetView:UITextField,addOnClickListener listener:OnKeyListener){
        self.textFiled = targetView;
        targetView.inputView = self
        self.onClickListener = listener
    }
    
    func createKey(titleTxt title:String,posX x:CGFloat, posY y:CGFloat, width w:CGFloat,hight h : CGFloat,forId id:NSInteger)->Void{
        self.createKey(titleTxt: title, posX: x, posY: y, width: w, hight: h, forId: id, normalImg: nil, highLightimg: nil)
    }
    
    func createKey(titleTxt title:String,
                   posX x:CGFloat,
                   posY y:CGFloat,
                   width w:CGFloat,
                   hight h : CGFloat,
                   forId id:NSInteger,normalImg norBgImg:String?, highLightimg himg:String?)->Void{
        
        let btnKey = UIButton();
        btnKey.frame = CGRect.init(x: x, y: y, width: w, height: h);
        self.addSubview(btnKey)
        btnKey.tag = id
        btnKey.setTitle(title, for: .normal)
        btnKey.setTitleColor(UIColor.black, for: .normal)
        btnKey.addTarget(self, action: #selector(onClickListener(button:)), for: .touchUpInside)
        guard let nImg = norBgImg else{
            btnKey.layer.cornerRadius = 5.0
            return
        }
        btnKey.setBackgroundImage(UIImage.init(named: nImg), for: .normal)
        guard let hImg = himg else{
            return
        }
        btnKey.setBackgroundImage(UIImage.init(named: hImg), for: .highlighted)
        
    }
    
    @objc func onClickListener(button:UIButton) {
        switch button.tag {
            case (0...10),(100...126):
                if self.onClickListener != nil {
                    self.onClickListener!.onClick?(button: button)
                }
                self.afterText.append(button.titleLabel!.text!)
                break;
                
            case ABC:
                switchKeyboardType()
                break;
            
        case SEARCH:
            
            break;
            
        case SWITCH_TYPE:
            switchKeyboardType()
            break;
            
        case CAPTIAL:
            switchCaptial(button: button)
            break;
                
            case DELETE:
                if !self.afterText.isEmpty{
                    let index = self.afterText.count - 1
                    self.afterText = self.afterText.prefix(index).description
                }
                break;
                
            case FINISH:
                hideKeyboard()
                break;
                
            default:
                break;
        }
        
        if self.onClickListener != nil && !(21...30).contains(button.tag){
            
            self.onClickListener?.addTextWatch?(button: button,
                                            beforeText: self.beforeText,
                                               curText: button.titleLabel!.text,
                                             afterText: self.afterText)
            self.beforeText = self.afterText;
        }
        
    }
    
    func hideKeyboard() {
        self.textFiled?.endEditing(true)
    }
    
    func switchCaptial(button view : UIButton) {
        
    }
    
    func switchKeyboardType() {
        
    }


}

  • 数字键盘类
import UIKit

class NumberKeyboard: KeyboardBaseView {
    
    lazy var logoLabel:UILabel = UILabel()
    var colSpace : CGFloat = 5.0;
    var rowSpace : CGFloat = 5.0
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.gray
        createLogoView()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func createView(inputView targetView: UITextField,addOnClickListener listener:OnKeyListener) {
        super.createView(inputView: targetView,addOnClickListener: listener)
        for view in self.subviews{
            view.removeFromSuperview()
        }
        let width = (self.frame.size.width - self.colSpace * 4) / 3
        let height = (self.frame.size.height - self.logoLabel.frame.size.height - self.rowSpace * 4 ) / 4
        for i in 1..<10{
            
            let indexColSpace = self.colSpace * CGFloat((i - 1) % 3)
            let indexWidth = width * CGFloat((i - 1) % 3)
            let x = self.colSpace + indexColSpace +  indexWidth
            
            let indexRowSpace = self.rowSpace * CGFloat((i - 1) / 3)
            let indexRowHeight = height * CGFloat((i - 1) / 3)
            let y = 44 + indexRowSpace + indexRowHeight
            
            createKey(titleTxt: String.init(format: "%d", i),
                      posX: x,
                      posY: y,
                      width: width,
                      hight: height,
                      forId: i,
                  normalImg: "anniu1.png",
               highLightimg: "anniu1_select.png")
        }
        
        createKey(titleTxt: "ABC",
                             posX: self.colSpace,
                             posY: self.logoLabel.frame.size.height + self.rowSpace * 3 + height * 3,
                             width: width,
                             hight: height,
                             forId: ABC,
                             normalImg: "anniu1.png",
                             highLightimg: "anniu1_select.png")
        
        createKey(titleTxt: String.init(format: "%d", 0),
                        posX: self.colSpace * 2 + width,
                        posY: self.logoLabel.frame.size.height + self.rowSpace * 3 + height * 3,
                        width: width,
                        hight: height,
                        forId: 0,
                        normalImg: "anniu1.png",
                        highLightimg: "anniu1_select.png")
        
        createKey(titleTxt: "X",
                        posX: self.colSpace * 3 + width * 2,
                        posY: self.logoLabel.frame.size.height + self.rowSpace * 3 + height * 3,
                        width: width,
                        hight: height,
                        forId: DELETE,
                        normalImg: "anniu1.png",
                        highLightimg: "anniu1_select.png")
        
        
    }
    
    func createLogoView(){
        self.logoLabel.frame = CGRect.init(x: 0, y: 0, width: self.frame.size.width, height: 44)
        self.addSubview(self.logoLabel)
        self.logoLabel.text = "硬汉安全键盘"
        self.logoLabel.textAlignment = .center
        logoLabel.font = UIFont.systemFont(ofSize: 14)
        logoLabel.textColor = UIColor.white
        
        let btnFinish = UIButton.init()
        btnFinish.frame = CGRect.init(x: self.frame.size.width - 100, y: 0, width: 100, height: 44)
        self.addSubview(btnFinish)
        btnFinish.tag = FINISH
        btnFinish.setTitle("完成", for: .normal)
        btnFinish.setTitleColor(UIColor.blue, for: .normal)
        btnFinish.addTarget(self, action: #selector(onClickListener(button:)), for:.touchUpInside)
        
    }
    
    override func switchKeyboardType() {
        var abcKeyboard = KeyboardMgr.shareInstace.keyboardInstanceDict[AbcKeyboard.self.description()]
               
       if(abcKeyboard == nil){
           abcKeyboard = AbcKeyboard.init(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 260))
           KeyboardMgr.shareInstace.keyboardInstanceDict[AbcKeyboard.self.description()] = abcKeyboard
       }
       KeyboardMgr.shareInstace.setInputMethodKeyboard(keyboardview: abcKeyboard!,
                                                       inputView: textFiled!,
                                                       onKeyClickListener: onClickListener!)
       textFiled?.reloadInputViews()
    }
    

}

  • 随机数字键盘类
import UIKit

class RandomNumberKeyboard: KeyboardBaseView {

    lazy var logoLabel        : UILabel = UILabel()
    var colSpace              : CGFloat = 5.0;
    var rowSpace              : CGFloat = 5.0
    lazy var randomNumArray   : NSMutableArray = NSMutableArray.init()
    
    override init(frame: CGRect) {
       super.init(frame: frame)
       self.backgroundColor = UIColor.gray
       createLogoView()
        
        for i in 0..<10 {
            randomNumArray.add(NSString.init(format: "%d", i))
        }
    }
       
   required init?(coder: NSCoder) {
       fatalError("init(coder:) has not been implemented")
   }
    
    func createLogoView(){
        self.logoLabel.frame = CGRect.init(x: 0, y: 0, width: self.frame.size.width, height: 44)
        self.addSubview(self.logoLabel)
        self.logoLabel.text = "硬汉安全键盘"
        self.logoLabel.textAlignment = .center
        logoLabel.font = UIFont.systemFont(ofSize: 14)
        logoLabel.textColor = UIColor.white
        
        let btnFinish = UIButton.init()
        btnFinish.frame = CGRect.init(x: self.frame.size.width - 100, y: 0, width: 100, height: 44)
        self.addSubview(btnFinish)
        btnFinish.tag = FINISH
        btnFinish.setTitle("完成", for: .normal)
        btnFinish.setTitleColor(UIColor.blue, for: .normal)
        btnFinish.addTarget(self, action: #selector(onClickListener(button:)), for:.touchUpInside)
        
    }
    
    override func createView(inputView targetView: UITextField, addOnClickListener listener: OnKeyListener) {
        super.createView(inputView: targetView, addOnClickListener: listener)
        createNumberAndRandom()
    }
    
    func createNumberAndRandom() {
        //随机乱序
        for i in (1...10).reversed() {
            let random = arc4random_uniform(UInt32(i))
            let tmp = self.randomNumArray[Int(random)];
            self.randomNumArray[Int(random)] = self.randomNumArray[i - 1];
            self.randomNumArray[i - 1] = tmp;
        }
        
        let width = (self.frame.size.width - self.colSpace * 4) / 3
        let height = (self.frame.size.height - self.logoLabel.frame.size.height - self.rowSpace * 4 ) / 4
        
        for(i, item)in randomNumArray.enumerated(){
            
            if(i == 0){
                createKey(titleTxt: item as! String,
                          posX: self.colSpace * 2 +  width,
                          posY: self.logoLabel.frame.size.height + self.rowSpace * 3 + height * 3,
                          width: width,
                          hight: height,
                          forId: i,
                          normalImg: "anniu1.png",
                          highLightimg: "anniu1_select.png")
                
            }else{
            
               let indexColSpace = self.colSpace + self.colSpace * CGFloat(i % 3)
               let indexWidth = width * CGFloat(i % 3)
               let x = indexColSpace +  indexWidth
               
               let indexRowSpace = self.logoLabel.frame.size.height + self.rowSpace * CGFloat((i - 1) / 3)
               let indexRowHeight = height * CGFloat((i - 1) / 3)
               let y = indexRowSpace + indexRowHeight
               
                createKey(titleTxt: item as! String,
                            posX: x,
                            posY: y,
                            width: width,
                            hight: height,
                            forId: i,
                            normalImg: "anniu1.png",
                            highLightimg: "anniu1_select.png")
            }
            
        }
        
        createKey(titleTxt: "ABC",
                             posX: self.colSpace,
                             posY: self.logoLabel.frame.size.height + self.rowSpace * 3 + height * 3,
                             width: width,
                             hight: height,
                             forId: ABC,
                             normalImg: "anniu1.png",
                             highLightimg: "anniu1_select.png")

        
        createKey(titleTxt: "X",
                        posX: self.colSpace * 3 + width * 2,
                        posY: self.logoLabel.frame.size.height + self.rowSpace * 3 + height * 3,
                        width: width,
                        hight: height,
                        forId: DELETE,
                        normalImg: "anniu1.png",
                        highLightimg: "anniu1_select.png")
    }
    
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        createNumberAndRandom()
    }

}

  • 英文键盘类
import UIKit

let SCREEN_WIDTH = UIScreen.main.bounds.width
let SCREEN_HEIGHT = UIScreen.main.bounds.height
let FIT_WIDTH = SCREEN_WIDTH / 320.0


class AbcKeyboard: KeyboardBaseView {

    lazy var array = NSMutableArray.init(objects:
        "q","w","e","r","t","y","u","i","o","p",
        "a","s","d","f","g","h","j","k","l",
        "z","x","c","v","b","n","m")
    var capitalKeyBgImg :UIImageView?
    
    override func createView(inputView targetView: UITextField, addOnClickListener listener: OnKeyListener) {
        super.createView(inputView: targetView, addOnClickListener: listener)
        for view in self.subviews{
            view.removeFromSuperview()
        }

        self.backgroundColor = UIColor.init(patternImage: UIImage.init(named: "bgs.png")!)
        for i in 0..<10{
            createKey(titleTxt: array[i] as! String,
                          posX: 1 + CGFloat(i) * 32.0 * FIT_WIDTH,
                          posY: 5 * FIT_WIDTH,
                         width: 34 * FIT_WIDTH,
                         hight: 48 * FIT_WIDTH,
                         forId: i + 100,
                     normalImg: "tu1 (2).png",
                  highLightimg: "tu1 2.png")
        }
        
        for i in 0..<9{
            createKey(titleTxt: array[i + 10] as! String,
                          posX: 16 + CGFloat(i) * 32.0 * FIT_WIDTH,
                          posY: 53 * FIT_WIDTH,
                         width: 34 * FIT_WIDTH,
                         hight: 48 * FIT_WIDTH,
                         forId: i + 110,
                     normalImg: "tu1 (2).png",
                  highLightimg: "tu1 2.png")
        }
        
        for i in 0..<7{
            createKey(titleTxt: array[i + 19] as! String,
                      posX: 46.0 * FIT_WIDTH + CGFloat(i) * 32.0 * FIT_WIDTH,
                          posY: 103 * FIT_WIDTH,
                         width: 34 * FIT_WIDTH,
                         hight: 48 * FIT_WIDTH,
                         forId: i + 119,
                     normalImg: "tu1 (2).png",
                  highLightimg: "tu1 2.png")
        }
        
        //删除键
        createKey(titleTxt: "",
                  posX: 272.0 * FIT_WIDTH,
                posY: 103 * FIT_WIDTH,
               width: 43 * FIT_WIDTH,
               hight: 49 * FIT_WIDTH,
               forId: DELETE,
           normalImg: "tu2 2.png",
        highLightimg: "tu2 (2).png")
        
        let deleteKeyBgImg = UIImageView.init(frame: CGRect.init(x: 277*FIT_WIDTH, y:113*FIT_WIDTH, width:32*FIT_WIDTH, height:28*FIT_WIDTH))
        deleteKeyBgImg.image = UIImage.init(named: "tu2 (3).png")
        self.addSubview(deleteKeyBgImg)
        
        //大小切换键
        createKey(titleTxt: "",
                  posX: 1.0 ,
                posY: 103 * FIT_WIDTH,
               width: 43 * FIT_WIDTH,
               hight: 49 * FIT_WIDTH,
               forId: CAPTIAL,
           normalImg: "tu2 2.png",
        highLightimg: "tu2 (2).png")
        
        let capitalKey = self.viewWithTag(CAPTIAL) as! UIButton
        capitalKey.setBackgroundImage(UIImage.init(named: "tu2 (2).png"), for: .selected)
        
        capitalKeyBgImg = UIImageView.init(frame: CGRect.init(x: 7*FIT_WIDTH, y:113*FIT_WIDTH, width:31*FIT_WIDTH, height:27*FIT_WIDTH))
        capitalKeyBgImg!.image = UIImage.init(named: "da_.png")
        self.addSubview(capitalKeyBgImg!)
        
        //数字123键
        createKey(titleTxt: "",
                  posX: 1.0 ,
                posY: 152 * FIT_WIDTH,
               width: 80 * FIT_WIDTH,
               hight: 49 * FIT_WIDTH,
               forId: SWITCH_TYPE,
           normalImg: "tu3-4",
        highLightimg: "tu3-04 (2).png")
        
        let num123Label = UILabel.init()
        num123Label.frame = self.viewWithTag(SWITCH_TYPE)!.frame
        num123Label.backgroundColor = UIColor.clear
        num123Label.textColor = UIColor.white
        num123Label.textAlignment = .center
        num123Label.font = UIFont.init(name: "STHeitiSC-Light", size: 18.0 * FIT_WIDTH)
        num123Label.text = "1 2 3"
        self.addSubview(num123Label)
        
        //space键
        createKey(titleTxt: " ",
                  posX: 80 * FIT_WIDTH,
                posY: 152 * FIT_WIDTH,
               width: 160 * FIT_WIDTH,
               hight: 49 * FIT_WIDTH,
               forId: SPACE,
           normalImg: "tu4 (2).png",
        highLightimg: "tu4 2.png")
        
        let spaceLabel = UILabel.init()
        spaceLabel.frame = self.viewWithTag(SPACE)!.frame
        spaceLabel.backgroundColor = UIColor.clear
        spaceLabel.textColor = UIColor.white
        spaceLabel.textAlignment = .center
        spaceLabel.font = UIFont.init(name: "STHeitiSC-Light", size: 18.0 * FIT_WIDTH)
        spaceLabel.text = " "
        self.addSubview(spaceLabel)
        
        createKey(titleTxt: " ",
                  posX: SCREEN_WIDTH - 80 * FIT_WIDTH,
                posY: 152 * FIT_WIDTH,
               width: 80 * FIT_WIDTH,
               hight: 49 * FIT_WIDTH,
               forId: SEARCH,
           normalImg: "tu4 (2).png",
        highLightimg: "tu4 2.png")
        
        let searchLabel = UILabel.init()
        searchLabel.frame = self.viewWithTag(SEARCH)!.frame
        searchLabel.backgroundColor = UIColor.clear
        searchLabel.textColor = UIColor.blue
        searchLabel.textAlignment = .center
        searchLabel.font = UIFont.init(name: "STHeitiSC-Light", size: 14.0 * FIT_WIDTH)
        searchLabel.text = "搜索"
        self.addSubview(searchLabel)
    }
    
    override func switchCaptial(button view: UIButton) {
        if view.isSelected {
            view.isSelected = false
            capitalKeyBgImg?.image = UIImage.init(named: "da_.png")
            
            for(idx,obj) in array.enumerated(){
                let tmp = obj as! String
                array[idx] = tmp.lowercased()
                let key = self.viewWithTag(100 + idx) as! UIButton
                key.setTitle(tmp.lowercased(), for: .normal)
            }
            
        }else{
            view.isSelected = true
            capitalKeyBgImg?.image = UIImage.init(named: "da.png")
            for(idx,obj) in array.enumerated(){
                let tmp = obj as! String
                array[idx] = tmp.uppercased()
                let key = self.viewWithTag(100 + idx) as! UIButton
                key.setTitle(tmp.uppercased(), for: .normal)
            }
            
        }
         
    }
    
    override func switchKeyboardType() {
        var numKeyboard = KeyboardMgr.shareInstace.keyboardInstanceDict[NumberKeyboard.self.description()]
        if(numKeyboard == nil){
            numKeyboard = NumberKeyboard.init(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 260))
            KeyboardMgr.shareInstace.keyboardInstanceDict[NumberKeyboard.self.description()] = numKeyboard
        }
        KeyboardMgr.shareInstace.setInputMethodKeyboard(keyboardview: numKeyboard!,
                                                        inputView: textFiled!,
                                                        onKeyClickListener: onClickListener!)
        textFiled?.reloadInputViews()
    }

}

  • 测试使用例子
import UIKit

class KeyboardVC: UIViewController {
    
    lazy var textFiled : UITextField = UITextField.init(frame: CGRect.init(x: 20, y: 150, width: 100, height: 50))

    override func viewDidLoad() {
        super.viewDidLoad()

        //重新创建一个barButtonItem
        self.navigationController?.isNavigationBarHidden = false

        let backItem = UIBarButtonItem.init(title: "Back", style: .done, target: self, action: #selector(onClickListener))
        backItem.tag = 50
        //设置backBarButtonItem即可
        self.navigationItem.leftBarButtonItem = backItem;
        self.navigationItem.title = "标题文字"
        self.view.backgroundColor = UIColor.white
        
    
        textFiled.backgroundColor = UIColor.gray
        self.view.addSubview(textFiled)
        
        let keyBoardView = AbcKeyboard.init(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 260))
        
        KeyboardMgr.init().setInputMethodKeyboard(keyboardview: keyBoardView, inputView: textFiled, onKeyClickListener: self)
        
        
    
        
        
    }
    
    @objc func onClickListener(){
        self.navigationController?.popViewController(animated: false)
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}

//实现键盘按钮点击协议
extension KeyboardVC:OnKeyListener{
    
    func onClick(button view: UIButton) {
        print("60---\(String(describing: view.titleLabel?.text))")
    }
    
    func addTextWatch(button view: UIButton, beforeText bStr: String?, curText cStr: String?, afterText aStr: String?) {
        print("65-----beforetext:\(bStr) curtext:\(cStr) aftertext:\(aStr)")
        textFiled.text = aStr
    }
}

objc 版本:

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger, KeyboardType) {
    DecimalNumber       = 0, //带小数点的数据键盘 九宫格布局
    NumberAndRandom     = 1, //随机出现数字键盘  九宫格布局
    Number              = 3, //纯数字键盘
    Default             = 4, //默认的英文键盘 26键布局
  
};


/// 键盘点击协议
@protocol OnKeyListener <NSObject>


@optional

/// 按键点击事件
/// @param Id 按键id
/// @param text 当前的文本
/// @param btn 按键对象
- (void)onClick:(NSInteger)Id withText:(NSString *_Nullable)text view:(UIButton*_Nullable) btn;

@optional
/// 文本输入监听协议接口
/// @param view 按键本身
/// @param beforeText 上一次输入的文本
/// @param curText 当前输入的文本
/// @param afterText 输入之后的文本
-(void) onTextWatch:(UIButton*_Nullable) view
         beforeText:(NSString*_Nullable) beforeText
            curText:(NSString*_Nullable)curText
          afterText:(NSString*_Nullable)afterText;

@end



NS_ASSUME_NONNULL_BEGIN

@interface KeyboardView : UIView
@property(assign,nonatomic) NSUInteger colSpace;
@property(assign,nonatomic) NSUInteger rowSpace;
@property(strong,nonatomic) UIView* containerView;
@property(strong, nonatomic) UITextField *tmpTextField;
@property(weak,nonatomic) id<OnKeyListener> keyClickListener;
@property(nonatomic,assign) KeyboardType type;


///  设置输入法键盘
/// @param type 类型
/// @param inputView 输入视图
-(void) setInputMethodKeyboard:(KeyboardType) type inputView:(UITextField*) inputView;

-(void) releaseRes;

@end

NS_ASSUME_NONNULL_END


#import "KeyboardView.h"
#import "AbcKeyBoardView.h"
#import <Foundation/Foundation.h>
#import "NSString+Des3.h"

#define FIT_X          [UIScreen mainScreen].bounds.size.width/320.000
#define iPhone4        ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 960), [[UIScreen mainScreen] currentMode].size) : NO)

const NSInteger ABC     = 23;
const NSInteger DELETE  = 24;

@interface KeyboardView(){
    UIButton *pressButtonCapital;
}
@property(strong,nonatomic) UIView* logoBgView;
@property(copy,nonatomic) NSString* beforeInputContent; //注意此处的修饰符,before为临时m赋值,用copy
@property(strong,nonatomic) NSMutableArray* randomNumArray;
@property(strong,nonatomic) AbcKeyBoardView* abcKeyboardView;

// 不能使用copy 因为可变对象的拷贝之后变成了为不可变对象,不能再进行内容追加
@property(strong,nonatomic) NSMutableString* afterInputContent;

@end

@implementation KeyboardView


- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        [self initConfig];
    }
    return self;
}

-(void) initConfig{
    self.rowSpace = 5;
    self.colSpace = 5;
    self.containerView = [UIView new];
    self.containerView.frame = self.frame;
    [self addSubview:self.containerView];
    self.afterInputContent = [[NSMutableString alloc] init];
    self.randomNumArray = [[NSMutableArray alloc] init];
    for (NSInteger i = 0;  i < 10; i ++) {
        [self.randomNumArray addObject:[NSString stringWithFormat:@"%ld",i]];
    }
}

/// 设置输入法键盘
/// @param type 类型
/// @param inputView 输入视图
-(void) setInputMethodKeyboard:(KeyboardType) type inputView:(UITextField*) inputView{
    if (!inputView) {
        return;
    }
    self.type = type;
    inputView.inputView = self;
    self.tmpTextField = inputView;
    switch (type) {
        case Default:
            [self createDefaultKeyvoardView];
            break;
        case Number:{
            [self createLogoView];
            [self createNumberKeyboardView];
            
        }
            break;
            
        case NumberAndRandom:
            [self createLogoView];
            break;
            
        default:
            break;
    }
}

- (void)createLogoView{
    self.logoBgView = [UIView new];
    [self setBackgroundColor:[UIColor darkGrayColor]];
    [self.containerView addSubview:self.logoBgView];
    self.logoBgView.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), 44);

    UILabel *logoLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.logoBgView.frame), CGRectGetHeight(self.logoBgView.frame))];
    [self.logoBgView addSubview:logoLabel];
    [logoLabel setText:@"硬汉安全键盘"];
    logoLabel.textAlignment = NSTextAlignmentCenter;
    [logoLabel setLineBreakMode:NSLineBreakByWordWrapping];
    [logoLabel setNumberOfLines:0];
    [logoLabel setFont:[UIFont systemFontOfSize:14]];
    [logoLabel setTextColor:[UIColor whiteColor]];

    UIButton *btnFinish = [[UIButton alloc]initWithFrame:CGRectMake(CGRectGetWidth(self.logoBgView.frame) / 4 * 3, 0, CGRectGetWidth(self.logoBgView.frame) / 4 , CGRectGetHeight(self.logoBgView.frame))];
    [self.logoBgView addSubview:btnFinish];
    [btnFinish setTitle:@"完成" forState:UIControlStateNormal];
    [btnFinish setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    [btnFinish addTarget:self action:@selector(hideKeyboard) forControlEvents:UIControlEventTouchUpInside];
}

-(void) createNumberKeyboardView{
    CGFloat width = (CGRectGetWidth(self.frame) - self.colSpace * 4) / 3;
    CGFloat height = (CGRectGetHeight(self.frame) - self.rowSpace * 4 - self.logoBgView.frame.size.height) / 4 ;
    for(NSInteger i = 1; i < 10; i ++){
        [self createKey:[NSString stringWithFormat:@"%ld",i]
                   posX:(self.colSpace + self.colSpace * ((i - 1) % 3) +  width * ((i - 1) % 3))
                   posY:(44 + self.rowSpace * ((i - 1) / 3) + height * ((i - 1)/3))
                  width:width
                 height:height
                  forId:i];
    }
    //创建最底部一排的功能键
    [self createKey:[NSString stringWithFormat:@"%@",@"ABC"]
               posX:(self.colSpace)
               posY:(self.logoBgView.frame.size.height + self.rowSpace * 3 + height * 3)
              width:width
             height:height
              forId:23];

    [self createKey:[NSString stringWithFormat:@"%@",@"0"]
                  posX:(self.colSpace * 2 +  width)
                  posY:(self.logoBgView.frame.size.height + self.rowSpace * 3 + height * 3)
                 width:width
                height:height
                 forId:0];

    [self createKey:[NSString stringWithFormat:@"%@",@"X"]
               posX:(self.colSpace * 3 +  width * 2)
               posY:(self.logoBgView.frame.size.height + self.rowSpace * 3 + height * 3)
              width:width
             height:height
              forId:24];
    
}


/// 创建随机数字键盘,即0-9数字在键盘的位置随机出现
-(void) createNumberAndRandom{
    //随机打乱
    for(NSInteger i = self.randomNumArray.count;i > 0; i --){
        NSInteger random = arc4random() % i;
        NSInteger tmp = [self.randomNumArray[random] intValue];
        self.randomNumArray[random] = self.randomNumArray[i - 1];
        self.randomNumArray[i - 1] = [NSNumber numberWithInteger:tmp];
    }
    CGFloat width = (CGRectGetWidth(self.frame) - self.colSpace * 4) / 3;
    CGFloat height = (CGRectGetHeight(self.frame) - self.rowSpace * 4 - self.logoBgView.frame.size.height) / 4 ;
    
    [self.randomNumArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
        NSString* value = [NSString stringWithFormat:@"%@",obj];
        if(idx == 0){
            [self createKey:value
                      posX:(self.colSpace * 2 +  width)
                      posY:(self.logoBgView.frame.size.height + self.rowSpace * 3 + height * 3)
                     width:width
                    height:height
                     forId:[value intValue]];
        }else{
            [self createKey:value
                      posX:(self.colSpace + self.colSpace * ((idx) % 3) +  width * ((idx) % 3))
                      posY:(self.logoBgView.frame.size.height + self.rowSpace * ((idx - 1) / 3) + height * ((idx - 1)/3))
                     width:width
                    height:height
                     forId:[value intValue]];
        }
    }];
    [self createKey:[NSString stringWithFormat:@"%@",@"ABC"]
              posX:(self.colSpace)
              posY:(self.logoBgView.frame.size.height + self.rowSpace * 3 + height * 3)
             width:width
            height:height
             forId:ABC];
    
    [self createKey:[NSString stringWithFormat:@"%@",@"X"]
              posX:(self.colSpace * 3 +  width * 2)
              posY:(self.logoBgView.frame.size.height + self.rowSpace * 3 + height * 3)
             width:width
            height:height
             forId:DELETE];
    
}


/// 创建英文字母键盘,默认的类型为本键盘
-(void) createDefaultKeyvoardView{
    self.abcKeyboardView = [[AbcKeyBoardView alloc] initWithFrame:self.frame];
    [self.abcKeyboardView createKeyboardView];
    [self addSubview:self.abcKeyboardView];
    
}

-(void) removeAllSubViews:(UIView*) parentView{
    if (parentView) {
        for(UIView *view in [parentView subviews]){
            [view removeFromSuperview];
        }
    }
}

- (void)createKey:(NSString *)title
             posX:(float)posX
             posY:(float)posY
            width:(float)width
           height:(float)height
            forId:(NSInteger) tag{
    UIButton *btnKey = [[UIButton alloc]initWithFrame:CGRectMake(posX, posY, width, height)];
    [self.containerView addSubview:btnKey];
    btnKey.layer.cornerRadius = 5;
    btnKey.tag = tag;
    [btnKey addTarget:self action:@selector(buttonDidClicked:) forControlEvents:UIControlEventTouchUpInside];
    [btnKey setTitle:title forState:UIControlStateNormal];
    [btnKey setBackgroundColor:[UIColor lightGrayColor]];
    //[btnKey setBackgroundImage:[CommonFunc imageWithColor:[UIColor orangeColor]] forState:UIControlStateHighlighted];
}

- (void)buttonDidClicked:(UIButton*)sender{
    self.tmpTextField.text = sender.titleLabel.text;
    
    switch (sender.tag) {
            
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 0:
            [self.afterInputContent appendString:sender.titleLabel.text];
        break;
            
        case ABC:
            
            break;
            
        case DELETE:{
            if(self.afterInputContent.length > 0){
                NSString* minusStr = [self.afterInputContent substringToIndex:self.afterInputContent.length - 1];
                [self.afterInputContent setString:minusStr] ;
            }
        }
            
            break;
            
        default:
            break;
    }
   
    if ([self.keyClickListener respondsToSelector:@selector(onClick:withText:view:)]) {
           [self.keyClickListener onClick:sender.tag withText:sender.titleLabel.text view:sender];
       }
    if ([self.keyClickListener respondsToSelector:@selector(onTextWatch:beforeText:curText:afterText:)]) {
        
        [self.keyClickListener onTextWatch:sender beforeText:self.beforeInputContent curText:sender.titleLabel.text afterText:self.afterInputContent];
        self.beforeInputContent = self.afterInputContent;
    }
       
}


- (void)willMoveToSuperview:(UIView *)newSuperview{
    if (self.type == NumberAndRandom) {
        [self createNumberAndRandom];
    }
    
}

-(void)layoutSubviews{
    [super layoutSubviews];

}

- (void)hideKeyboard{
    [self.tmpTextField endEditing:YES];
    //[self.tmpTextField resignFirstResponder];
}

-(void) releaseRes{
    self.beforeInputContent = nil;
    self.afterInputContent = nil;
}

@end


  • 测试
@interface KeyboardVC ()<OnKeyListener>
@property(strong,nonatomic) UITextField* textField;
@property(strong,nonatomic) KeyboardView* keyboardView;

@end

@implementation KeyboardVC

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    self.textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 40, 200, 50)];
    self.textField.backgroundColor = [UIColor grayColor];
    [self.view addSubview:self.textField];
    
    self.keyboardView = [[KeyboardView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, 260)];
    
    //self.textField.inputView = self.keyboardView;
    //self.keyboardView.m_textField = self.textField;
    [self.keyboardView setInputMethodKeyboard:Number inputView:self.textField];
    [self.keyboardView setKeyClickListener:self];
    
    [self setUpForDismissKeyboard];

    
}
#pragma OnKeyListener 协议实现方式
- (void)onClick:(NSInteger)Id withText:(NSString *)text view:(UIButton *)btn{
    
}
-(void) onTextWatch:(UIButton*_Nullable) view
         beforeText:(NSString*_Nullable) beforeText
            curText:(NSString*_Nullable) curText
          afterText:(NSString*_Nullable) afterText{
    NSLog(@"37-------before:%@  curtext:%@  afterText:%@",beforeText,curText,afterText);
    self.textField.text = afterText;
   
}
//  end

//除输入框之外 ,点击屏幕其他地方收起键盘
- (void)setUpForDismissKeyboard {
  NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
  UITapGestureRecognizer *singleTapGR =
  [[UITapGestureRecognizer alloc] initWithTarget:self
                                          action:@selector(tapAnywhereToDismissKeyboard:)];
  NSOperationQueue *mainQuene =[NSOperationQueue mainQueue];
  [nc addObserverForName:UIKeyboardWillShowNotification
                  object:nil
                   queue:mainQuene
              usingBlock:^(NSNotification *note){
                [self.view addGestureRecognizer:singleTapGR];
              }];
  [nc addObserverForName:UIKeyboardWillHideNotification
                  object:nil
                   queue:mainQuene
              usingBlock:^(NSNotification *note){
                [self.view removeGestureRecognizer:singleTapGR];
              }];
}

- (void)tapAnywhereToDismissKeyboard:(UIGestureRecognizer *)gestureRecognizer {
  [self.view endEditing:YES];
}


@end

相关标签: IOS