• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Swift封装类似支付宝中的支付键盘(数字键盘)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

当我们在项目中有支付场景的时候,系统键盘可能有时候满足不了我们的需求了,这时候就需要我们自己来封装支付键盘,并添加一些逻辑校验,以保证良好的用户体验。


这是给键盘加的一些规则:

① 首位输入0后,不可继续输入整数,可输入小数点及小数点后两位

② 首位不可输入小数点,若有小数点,小数点后最多可输入两位数

③ 最多可输入9位整数,之后可输入小数点,不可再输入整数

④ 光标移动删除小数点,若小数点前只有整数0,则不能删除,若是非0整数则删除小数点,保留小数点后两位数

⑤ 长按删除键,可连续删除


界面大概是这样的:



下面直接贴代码,封装了一个键盘工具类,可以拿来直接用:

//

//  NumberKeyboard.swift

//  JiuLiFunds

//

//  Created by yangyunfei on 2018/1/5.

//  Copyright © 2018年 JiuLiFunds. All rights reserved.

//


//封装 浮点数 数字键盘


import UIKit


class NumberKeyboard: UIView {


    let baseTag = 1000

    

    weak var firstResponder:UITextField?

    var deleteTimer:Timer?

    var done: (() -> Void)?  /*< 点击确定执行的回调 */

    

    override init(frame:CGRect) {

        let rect =makeRect(x: 0, y:0, width: kScreenWidth * BiLi_SCREENWIDTH_NORMAL, height:200 * BiLi_SCREENHEIGHT_NORMAL)

        super.init(frame: rect)

        

        createUI()

    }

    required init?(coder aDecoder:NSCoder) {

        fatalError("init(coder:) has not been implemented")

    }

    

    func createUI() {

        

        self.backgroundColor =UIColor.hexToUIColor(sourceString:"dddddd")

        for i in0..<14 {

            let btn = UIButton(type: .custom)

            btn.backgroundColor = WHITECOLOR

            //设置高亮时按钮背景颜色

            btn.setBackgroundImage(UIImage.imageWithColor(color:UIColor.hexToUIColor(sourceString:"e5e5e5")), for: .highlighted)

            switch i {

            case 10://小数点

                btn.tag = baseTag + i

                btn.titleLabel?.font =FONT24

                btn.setTitleColor(TITLTEXTECOLOR, for: .normal)

                btn.setTitle(".", for: .normal)

            case 11://键盘

                btn.tag = baseTag + i

                btn.setImage(UIImage.init(named:"current_keyboard_hidden"), for: .normal)

            case 12://删除

                btn.tag = baseTag + i

                btn.setImage(UIImage.init(named:"current_keyboard_delete"), for: .normal)

                let longPressGR = UILongPressGestureRecognizer(target: self, action:#selector(deleteItemLongPress))

                btn.addGestureRecognizer(longPressGR)

            case 13://确定

                btn.tag = baseTag + i

                btn.setTitle("确定", for: .normal)

                btn.titleLabel?.font =FONT18

                btn.setTitleColor(WHITECOLOR, for: .normal)

                btn.backgroundColor = UIColor.hexToUIColor(sourceString: "0084ff")

            default:

                btn.tag = baseTag + i

                btn.setTitle(String(i), for: .normal)

                btn.titleLabel?.font =FONT24

                btn.setTitleColor(TITLTEXTECOLOR, for: .normal)

            }

            btn.addTarget(self, action:#selector(btnClickAction), for: .touchUpInside)

            self.addSubview(btn)

        }

    }

    

    override func layoutSubviews() {

        super.layoutSubviews()

        let width:CGFloat = (self.frame.width -1.5) / 4.0

        let height:CGFloat = (self.frame.height -1.5) / 4.0

        let lineWidth:CGFloat =0.5

        

        //数字1

        self.viewWithTag(baseTag +1)?.frame =makeRect(x: 0, y: lineWidth, width: width, height: height)

        //数字2

        self.viewWithTag(baseTag +2)?.frame =makeRect(x: width + lineWidth, y: lineWidth, width: width, height: height)

        self.viewWithTag(baseTag +3)?.frame =makeRect(x: 2 * width +2 * lineWidth, y: lineWidth, width: width, height: height)

        self.viewWithTag(baseTag +4)?.frame =makeRect(x: 0, y: height + lineWidth*2, width: width, height: height)

        self.viewWithTag(baseTag +5)?.frame =makeRect(x: width + lineWidth, y: height + 2*lineWidth, width: width, height: height)

        self.viewWithTag(baseTag +6)?.frame =makeRect(x: 2 * width +2 * lineWidth, y: height + 2*lineWidth, width: width, height: height)

        self.viewWithTag(baseTag +7)?.frame =makeRect(x: 0, y: (height + lineWidth)*2+lineWidth, width: width, height: height)

        self.viewWithTag(baseTag +8)?.frame =makeRect(x: width + lineWidth, y: (height + lineWidth)*2+lineWidth, width: width, height: height)

        self.viewWithTag(baseTag +9)?.frame =makeRect(x: (width + lineWidth)*2, y: (height + lineWidth)*2+lineWidth, width: width, height: height)

        

        //小数点

        self.viewWithTag(baseTag +10)?.frame =makeRect(x: 0, y: (height + lineWidth)*3+lineWidth, width: width, height: height)

        //零

        self.viewWithTag(baseTag +0)?.frame =makeRect(x: width + lineWidth, y: (height + lineWidth)*3+lineWidth, width: width, height: height)

        //键盘

        self.viewWithTag(baseTag +11)?.frame =makeRect(x: (width + lineWidth)*2, y: (height + lineWidth)*3+lineWidth, width: width, height: height)

        //删除

        self.viewWithTag(baseTag +12)?.frame =makeRect(x: (width + lineWidth)*3, y: lineWidth, width: width, height:2*height+2*lineWidth)

        //确定

        self.viewWithTag(baseTag +13)?.frame =makeRect(x: 3*width + lineWidth*2, y:2*height + 2*lineWidth, width: width, height:2*height+2*lineWidth)

    }

    

    @objc func btnClickAction(sender:UIButton) {

        

        let btnTag = sender.tag

        switch (btnTag) {

        case baseTag +10:

            self.clickedDot();

        case baseTag +11:

            self.clickedKeyBoard()

        case baseTag +12:

            self.clickedDelete()

        case baseTag +13:

            self.clickedSure()

            

        default://数字

            self.clickedNumber(num: btnTag -baseTag)

        }

        

    }

    //输入

    func insert(text: String) {

        let delegate =  self.firstResponder?.delegate

        let range = selectedRange(inputView: self.firstResponder)

        //回调代理方法

       delegate?.textField!(self.firstResponder!, shouldChangeCharactersIn: range, replacementString: text)

        

        self.firstResponder?.insertText(text)

    }

    func selectedRange(inputView: UITextField?) -> NSRange {

        let beginning: UITextPosition? = inputView?.beginningOfDocument

        let selectedRange: UITextRange? = inputView?.selectedTextRange

        let selectionStart: UITextPosition? = selectedRange?.start

        let selectionEnd: UITextPosition? = selectedRange?.end

        let location: Int = inputView!.offset(from: beginning ??UITextPosition(), to: selectionStart ?? UITextPosition())

        let length: Int = inputView!.offset(from: selectionStart ??UITextPosition(), to: selectionEnd ?? UITextPosition())

        return NSRange(location: location, length: length)

    }

    //点击小数点

    func clickedDot() {

        let text = self.firstResponder?.text

        //首位不能输入.    只能输入一个.

        if text?.count !=0 && !(text?.contains("."))! {

            self.insert(text:".")

        }

    }

    //点击删除

    @objc func clickedDelete() {

        if (self.firstResponder?.hasText)! {

            //光标Range

            let selectRange = self.firstResponder?.selectedTextRange

            //获取光标的位置

            let beginning = self.firstResponder?.beginningOfDocument

            let location = self.firstResponder?.offset(from: beginning!, to: (selectRange?.start)!)

            let str = NSString.init(string: (self.firstResponder?.text)!)

            if str.length <=1{

                self.firstResponder?.deleteBackward()

                self.insert(text:"")

                return

            }

            if str.substring(with:NSRange.init(location:0, length: 1)) =="0" && str.substring(with:NSRange.init(location:1, length: 1)) =="."  && str.length !=2 && location == 2{

                //光标移动删除小数点,若小数点前只有整数0,则不能删除

                return

            }else{

                self.firstResponder?.deleteBackward()

                self.insert(text:"")

            }

            

        }

    }

    //点击键盘

    func clickedKeyBoard() {

        self.firstResponder?.resignFirstResponder()

    }

    //点击确定

    func clickedSure() {

        self.firstResponder?.resignFirstResponder()

        if self.done !=nil {

            self.done!()

        }

    }

    //点击数字

    func clickedNumber(num:Int) {

        let text = self.firstResponder?.text

        //首位输入0后,不可继续输入整数,可输入小数点及小数点后两位

        if text?.count ==1 && text == "0" {

            return

        }

        if (text?.contains("."))! {

            //小数点后最多2位

            let index = text?.index(of:".")

            let subStr = text?.substring(from: index!)

            let cout = subStr?.count

            if cout! <= 2 {

                self.insert(text:String(num))

            }

        }

        else {//无小数点

            //整数最多可以输入9位

            let cout = text?.count

            if cout! < 9{

                self.insert(text:String(num))

            }

            

        }

        

    }

    

    //长按删除

    @objc func deleteItemLongPress(longPress:UILongPressGestureRecognizer) {

        if longPress.state == .began {

            deleteTimer = Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(repeatLongPressDelete), userInfo:nil, repeats: true)

        }else if (longPress.state == .ended || longPress.state == .failed || longPress.state == .cancelled){

            self.cleanTimer()

        }

    }

    @objc func repeatLongPressDelete() {


        if (self.firstResponder?.hasText)! {

            self.firstResponder?.deleteBackward()

            self.insert(text:"")

        }

    }

    func cleanTimer() {

        deleteTimer?.invalidate()

        deleteTimer =nil

    }

}


在需要使用的地方,这样调用,将数字键盘作为UITextField的inputView即可:

//自定义数字键盘

        let keyBoardView = NumberKeyboard()

        keyBoardView.firstResponder = moneyTextField

        moneyTextField.inputView = keyBoardView

        moneyTextField.reloadInputViews()



鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
swift4 代理的写法发布时间:2022-07-13
下一篇:
swift @AUTOCLOSURE 和 ?? ||发布时间:2022-07-13
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap