美文网首页
swift-本地验证码

swift-本地验证码

作者: aggie1024 | 来源:发表于2019-12-31 15:04 被阅读0次

    //1.定义继承自UIView的CaptchaView,直接上代码

    import UIKit
    // MARK: 基本的样式
    struct CaptchaViewStytel {
        
        /// 随机颜色
        var kRandomColor:UIColor{
            return UIColor.init(red: CGFloat(Float(arc4random()%255)/255.0), green: CGFloat(Float(arc4random()%255)/255.0), blue: CGFloat(Float(arc4random()%255)/255.0), alpha: 1.0)
        }
        /// 线数量
        var kLineCount = 6
        /// 线宽
        var kLineWidth = 1.0
        /// 字符数量
        var kCharCount = 4
        /// 随机字体大小
        var kFontSize:UIFont?{
            return UIFont.systemFont(ofSize: CGFloat(Float(arc4random()%5) + 18))
        }
    }
    class CaptchaView: UIView {
    
        /// 字符素材数组
         var changeArray: NSArray?
         /// 验证码的字符串
         var changeString: String?
         /// 基本样式
         var stytel:CaptchaViewStytel!
         
         override init(frame: CGRect) {
             super.init(frame: frame)
             
             // 初始化
             self.setUpUI()
             // 显示一个随机验证码
             self.changeCaptcha()
             
         }
         
         required init?(coder aDecoder: NSCoder) {
             fatalError("init(coder:) has not been implemented")
         }
         
         
         // MARK: 初始化
         func setUpUI() -> Void {
            
           let stytel = CaptchaViewStytel()
           self.stytel = stytel
             
           self.backgroundColor = stytel.kRandomColor
            
           //设置layer圆角半径
           //self.layer.cornerRadius = 5.0
           //隐藏边界
           //self.layer.masksToBounds = true
             
         }
         
          // MARK: 布局约束
         override func layoutSubviews() {
             super.layoutSubviews()
         }
         
         override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
             self.backgroundColor = stytel.kRandomColor
            
             //点击界面,切换验证码
             self.changeCaptcha()
             
             //setNeedsDisplay调用drawRect方法来实现view的绘制
             self.setNeedsDisplay()
         }
         
         
        // MARK: 显示一个随机验证码
         func changeCaptcha(){
           
             // 从字符数组中随机抽取相应数量的字符,组成验证码字符串
             // 数组中存放的是全部可选的字符,可以是字母,也可以是中文
             let changeArray = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
             self.changeArray = changeArray as NSArray
             self.changeString = String()
             
             // 随机从数组中选取需要个数的字符,然后拼接为一个字符串
             for _  in 0..<stytel.kCharCount {
                 
                 let index = arc4random()%(UInt32(changeArray.count - 1))
                 
                 let getStr = changeArray[Int(index)]
                 
                 self.changeString = "\(self.changeString!)\(getStr)"
             
             }
             
             // 从网络获取字符串,然后把得到的字符串在本地绘制出来(网络获取步骤在这省略)
             print("\(self.changeString!)")
           
         }
         
         // MARK:绘制界面(1.UIView初始化后自动调用; 2.调用setNeedsDisplay方法时会自动调用)
          override func draw(_ rect: CGRect) {
             
             // 重写父类方法,首先要调用父类的方法
              super.draw(rect)
            
             //设置随机背景颜色
             self.backgroundColor = stytel.kRandomColor
             
             //获得要显示验证码字符串,根据长度,计算每个字符显示的大概位置
             let text = self.changeString
         
             let cSize = NSString(string: "S").size(withAttributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 20)])
             // 每个字符显示宽度的位置
             let width = (rect.size.width / CGFloat(text!.count)) - CGFloat(cSize.width)
             // 每个字符所显示高度位置
             let height = rect.size.height - cSize.height
             
             var point: CGPoint
             
             //依次绘制每一个字符,可以设置显示的每个字符的字体大小、颜色、样式等
             var pX,PY: CGFloat
            
             for i in 0..<text!.count {
                 
                 pX = CGFloat(Float(arc4random()%UInt32(width))) + rect.size.width / CGFloat(text!.count)*CGFloat(i)
                 PY = CGFloat(Float(arc4random()%UInt32(height)))
                 point = CGPoint(x: pX, y: PY)
                 
                 let texta = text! as NSString
                 
                 let c = texta.character(at: i)
                 let textC = NSString(format: "%C", c)
             
                 textC.draw(at: point, withAttributes: [NSAttributedString.Key.font : stytel.kFontSize!])
             }
             
        //调用drawRect:之前,系统会向栈中压入一个CGContextRef,调用UIGraphicsGetCurrentContext()会取栈顶的CGContextRef
             let context = UIGraphicsGetCurrentContext()
             // 设置画线宽度
             context?.setLineWidth(CGFloat(stytel!.kLineWidth))
             
             // 绘制干扰的彩色直线
             for _ in 0..<stytel.kLineCount {
                
                 // 设置线的随机颜色
                 context?.setStrokeColor(stytel!.kRandomColor.cgColor)
                 
                 // 设置线的起点
                 pX = CGFloat(Float(arc4random()%UInt32(rect.size.width)))
                 PY = CGFloat(Float(arc4random()%UInt32(rect.size.height)))
                 context?.move(to: CGPoint(x: pX, y: PY))
                 
                //设置线终点
                 pX = CGFloat(Float(arc4random()%UInt32(rect.size.width)))
                 PY = CGFloat(Float(arc4random()%UInt32(rect.size.height)))
                 context?.addLine(to: CGPoint(x: pX, y: PY))
                
                 // 画线
                 context?.strokePath()
             }
         }
         
    
    }
    
    

    2.使用

    import UIKit
    class LSLoginViewController: LSBaseController, UITextFieldDelegate {
    
    var captchaView : CaptchaView!//本地验证码
    var tex_CompanyCode: UITextField!//验证码
    
    override func viewDidLoad() {
            super.viewDidLoad()
            addSubViews()
    }
    
    func addSubViews(){
     //显示验证码界面
            captchaView = CaptchaView.init()
            headeBGView.addSubview(captchaView)
            captchaView.snp.makeConstraints { (make) in
                make.right.equalTo(headeBGView).offset(-RESIZE(x: 20))
                make.top.equalTo(tex_CompanyCode)
                make.width.equalTo(RESIZE(x: 100))
                make.height.equalTo(RESIZE(x: 30))
            }
    
     tex_CompanyCode = createTextField(content: "验证码")
           headeBGView.addSubview(tex_CompanyCode)
           tex_CompanyCode.clearButtonMode = UITextField.ViewMode.never //编辑时出现清除按钮
           tex_CompanyCode.snp.makeConstraints { (make) in
               make.left.height.equalTo(tex_UserName)
               make.right.equalTo(headeBGView.snp.right).offset(-RESIZE(x: 120))
               make.centerY.equalTo(imageCompanyCode.snp.centerY)
           }
    }
    
     @objc func btn_ClickLogin(sender: UIButton){
          if tex_CompanyCode.text?.lowercased() !=   captchaView.changeString?.lowercased() {
                    //本地验证码不正确
                    let anim = CAKeyframeAnimation.init(keyPath: "transform.translation.x")
                   anim.repeatCount = 1
                   anim.values = [-20,20,-20]
                   captchaView.layer.add(anim, forKey: nil)
                   tex_CompanyCode.layer.add(anim, forKey: nil)
                   self.showToast("验证码错误,请重新输入")
                   return
                }
    LSPrint(message: "登录请求")
    }
    
    }
    

    相关文章

      网友评论

          本文标题:swift-本地验证码

          本文链接:https://www.haomeiwen.com/subject/fzwboctx.html