zoukankan      html  css  js  c++  java
  • ios自定义数字键盘

    因为项目又一个提现的功能,textfiled文本框输入需要弹出数字键盘,首先想到的就是设置textfiled的keyboardType为numberPad,此时你会看到如下的效果:


     

    但是很遗憾这样设置虽然出现了数字键盘,但是对于我们提现的这个功能来说是需要小数的,所以需要一个小数点 但是使用上面的键盘显然不能满足我们的需求,那么应该如何解决这样的问题呢? 想了一下,有两个方法取实现:

    1.自定义一个键盘视图

    2.在系统键盘的基础上修改

    经过思考,自定义键盘代价太大,所以我才用了第二种方法。

    为了在系统键盘基础上修改,首先我们需要拿到键盘,那么如何拿到呢?我们知道键盘也是一个window, 所以最简单的方式就是打印出当前视图上面的window,拿到键盘所属的window,然后遍历内部的子控件即可 但是我没有直接取打印,我直接通过程序的调用栈就可以看到当前键盘所属的window及其内部的子控件,以下是我通过程序调用栈看到的结果:


     

    可以看到键盘是一个名字叫UIRemoteKeyboardWindow的window 管理的,然后通过上图可以看到真正键盘输入视图应该是叫UIInputSetHostView,真正的键盘面板的父视图是一个叫UIKBKeyplaneView的view ,我们可以看到UIKBKeyplaneView李 main的第一个子控件是一个叫UIKBSplitImageView 这个就是底部的删除按钮(暂且我们就叫里面的每一个控件为按钮吧)剩余的都对应于 1 2 3 4 5 6 7 8 9 0 这几个控件 都是UIKBKeyView类型的。

    通过上面的分析之后,我们就很好做了,我们只需要拿到键盘面板视图 在它上面添加一个小数点按钮 即可。注意如果添加子控件需要响应事件,必须添加到UIKBKeyplaneView这个视图上面,否则添加的子控件将无法响应事件。

    通过上面分析我们就很好下手了, 所以接下来我们上代码:

    第一步自定义一个小数点按钮:

    /// 自定义键盘小数点按钮
    
    lazyvarpointBtn:UIButton= {
    
      letpointBtn = UIButton()
    
      pointBtn.frame = CGRect(x:0, y:162, 106, height:54)
    
      pointBtn.setTitle(".", for: .normal)
    
      pointBtn.tag =0xffbb33
    
      pointBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize:35)
    
      pointBtn.setTitleColor(UIColor.black, for: .normal)
    
      pointBtn.addTarget(self, action:#selector(pointBtnClick), for: .touchUpInside)
    
      return pointBtn
    
    }()

    然后我们需要监听键盘将要显示的通知,在键盘将要显示的时候添加我们自己的按钮,我们在控制器里实现如下代码:

    //监听键盘弹出

    NotificationCenter.default.addObserver(self, selector:#selector(keyBoardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object:nil)

    然后实现监听方法:

    //键盘的出现

    func keyBoardWillShow(_notification:Notification){
    
        addPointBtn()
    
    }
    /// 添加小数点按钮
        func addPointBtn(){
            var foundKeyboard:UIView?
            var keyboardWindow:UIWindow?
            for testWindow in UIApplication.shared.windows {
                if testWindow.description.hasPrefix("<UIRemoteKeyboardWindow") {
                    keyboardWindow = testWindow
                    break
                }
            }
            if (keyboardWindow == nil) {return}
            for possibleKeyboard in keyboardWindow!.subviews {
                MyLog(message: "keyboardWindow==(possibleKeyboard)")
                if possibleKeyboard.description.hasPrefix("<UIInputSetContainerView") {
                    MyLog(message: "possibleKeyboard==(possibleKeyboard)")
                    for possibleKeyboard_2 in possibleKeyboard.subviews {
                        MyLog(message: "possibleKeyboard_2==(possibleKeyboard_2)")
                        if possibleKeyboard_2.description.hasPrefix("<UIInputSetHostView") {
                            //查找键盘面板视图
                          foundKeyboard = findInputPlaneView(superView: possibleKeyboard_2)
                            //添加按钮
                            if (foundKeyboard != nil) {
                                //如果没有添加过小数点按钮就添加
    //                            if (foundKeyboard!.viewWithTag(0xffbb33) == nil) {
                                    foundKeyboard!.addSubview(pointBtn)
                                    MyLog(message: "添加小数点按钮")
    //                            }
                            }
                          return
                        }
                    }
                }
            }
        }
        
        /// 查找键盘的面板视图
        func findInputPlaneView(superView:UIView)->UIView?{
            var planeView:UIView?
            for subview in superView.subviews {
                if subview.description.hasPrefix("<UIKBKeyplaneView") {
                    MyLog(message: "找到键盘面板")
                    return subview
                }else{
                   planeView = findInputPlaneView(superView: subview)
                }
            }
            return planeView
        }

    最后我们再实现小数点按钮点击的事件即可:

        /// 小数点按钮的点击
        func pointBtnClick(){
            //如果没有输入内容 直接退出
            if textField.text == nil || textField.text == "" {
                return
            }
            //判断是否已经输入了小数点
            if !textField.text!.contains(".") { //如果没有输入小数点就添加小数点到当前内容的末尾
                let oldStrin = textField.text!.appending(".")
                textField.text = oldStrin
            }
            MyLog(message: "pointBtnClickpointBtnClickpointBtnClickpointBtnClick")
        }
        

    然后运行项目之后,你会发现键盘左下角就添加了我们自己的小数点按钮了。


     

    小数点按钮的位置是通过计算的,通过打印我发现了键盘的高度为216 ,键盘宽度肯定是屏幕的宽度,然后每行每列显示的视图个数固定,想想你知道如何算的。

    现在我们的小数点就可以输入了,接下来最后一步限制用户只能输入小数点后面两位,

    实现textfield的代理方法

    //限制只能输入金额
    
    functextField(_textField:UITextField, shouldChangeCharactersIn range:NSRange, replacementString string:String) ->Bool{
    
    letnewString = (textField.text!asNSString).replacingCharacters(in: range, with: string)
    
    letexpression ="^[0-9]*((\.)[0-9]{0,2})?$"
    
    letregex =try! NSRegularExpression(pattern: expression, options: NSRegularExpression.Options.allowCommentsAndWhitespace)
    
    letnumberOfMatches = regex.numberOfMatches(in: newString, options:NSRegularExpression.MatchingOptions.reportProgress, range: NSMakeRange(0, (newStringasNSString).length))
    
    return numberOfMatches !=0
    
    }

    到此基本就完成了我们想要的效果了

  • 相关阅读:
    浅谈易语言“蓝屏”暗桩查找和处理方法
    解密入门教学(1-6)
    IOS之计算器实现
    瓦片地图与geoserver发布
    Mac使用入门
    postgres与osm初步使用
    python异步爬虫
    操作系统之死锁
    Android之IPC机制
    Android之WebView学习
  • 原文地址:https://www.cnblogs.com/syios/p/7692393.html
Copyright © 2011-2022 走看看