九宫格手势解锁

17 篇文章 0 订阅

手势解锁 九宫格解锁

  • 项目上用到了 手势解锁 没有时间自己去慢慢摸索 就直接在git上 找了些比较容易实现的项目进行修改后拿来使用 顺便把修改的代码 也放出 供以后自己和大家使用吧
  • 参考的git项目地址https://github.com/smlkts/IZGestureLockSwift 非常感谢大佬的开源 给我节省了好多时间

这个项目的git地址demo地址

- 代码实现

  //
  //  ViewController.swift
  //  AiiGestureLockView
  //
  //  Created by Sico2Sico on 02/09/2018.
  //  Copyright (c) 2018 Sico2Sico. All rights reserved.
  //

  import UIKit
  import SnapKit
  import AiiGestureLockView

  class ViewController: UIViewController {


      var passward = ""

      override func viewDidLoad() {
          super.viewDidLoad()
          view.backgroundColor = UIColor.white



          // 1 创建View 添加到容器
          let gestureLockView = AiiGestureLock()
          view.addSubview(gestureLockView)

          // 2 设置item大小  默认为48
          gestureLockView.itemSize = CGSize(width: 46, height: 46)

          // 3 设置内边距 默认为10个单位
          gestureLockView.contentInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)

          // 4 设置完成时 回调处理block
          gestureLockView.didFinishDrawing = {[weak self] (_ lockView: AiiGestureLock, _ password: String) in


              if lockView.lockType == .create {
                  if password.count < 5 {
                      print("不能小于五个数")
                      lockView.errorShow(withDuration: 1.0, completion:nil)
                      return
                  }

                  self?.passward = password
                  lockView.clean()
                  lockView.lockType = .confirm
                  return
              }


              if lockView.lockType == .confirm {

                  if password == self?.passward {
                      print("验证成功")
                      lockView.clean()
                      lockView.lockType = .verify
                      return
                  }else {
                      print("验证失败")
                      lockView.errorShow(withDuration:1, completion:nil)
                      return
                  }
              }

              if lockView.lockType == .verify {
                  if password == self?.passward {
                      print("密码正确")
                      lockView.clean()
                      lockView.lockType = .create
                      return
                  }else {
                      print("密码错误")
                      lockView.errorShow(withDuration:1, completion:nil)
                      return
                  }
              }
          }

          gestureLockView.snp.makeConstraints { (make) in
              make.size.equalTo(200)
              make.center.equalToSuperview()
          }


      }
  }

源码

//
//  AiiGestureLock.swift
//  AppUIKit
//
//  Created by 德志 on 2018/2/8.
//

import UIKit

public class AiiGestureLock: UIControl {

    /// 设置类型
    public var lockType : LockType = .create

    /// 线宽
    public var lineWidth : CGFloat = 10

    /// 按钮的大小
    public var itemSize = CGSize(width:48.0, height:48.0)

    /// view的内边距
    public var contentInset = UIEdgeInsetsMake(10, 10, 10, 10)

    /// 颜色 
    public var lineColor : UIColor = UIColor(red: 255/255.0, green: 174/255.0, blue: 0.0, alpha: 1)
    /// 错误的颜色
    public var errorLineColor : UIColor = UIColor.red


    /// 选中的点
    private var selectPoints = Array<UIButton>()

    /// 手指点
    private var fingerPoint: NSValue?

    /// 完成回调 所有的逻辑事件都在这里处理
    public var didFinishDrawing: ((_ lockView: AiiGestureLock, _ password: String) -> Void)? = nil


    /// 画线的layer层
    private lazy var drawingLayer: CAShapeLayer = {
        let drawLayer = CAShapeLayer()
        drawLayer.strokeColor = lineColor.cgColor
        drawLayer.lineWidth = lineWidth
        drawLayer.lineCap = kCALineCapRound
        drawLayer.lineJoin = kCALineJoinRound
        drawLayer.fillColor = UIColor.clear.cgColor
        drawLayer.strokeStart = 0.0
        drawLayer.strokeEnd = 1.0
        layer.insertSublayer(drawLayer, at: 0)
        return drawLayer
    }()

    /// 按钮数组
    private lazy var btns : [UIButton] = {
        var points = Array<UIButton>()
        for i in 0 ..< 9 {
            let btn  = UIButton(type: UIButtonType.custom)
            btn.tag = i + 1
            btn.isUserInteractionEnabled = false
            btn.isSelected = false
            points.append(btn)
            addSubview(btn)
        }
        return points
    }()


    public override init(frame: CGRect) {
        super.init(frame: frame)

        setNormalImage(image:UIImage(named:"p_nomal", in:Bundle.aiiResourceBundle(), compatibleWith: nil)!)
        setBackGgImage(image:UIImage(named:"p_nomal", in:Bundle.aiiResourceBundle(), compatibleWith: nil)!)
        setSelectedImage(image:UIImage(named:"p_select", in:Bundle.aiiResourceBundle(), compatibleWith: nil)!)
        setHighlightedImage(image:UIImage(named:"p_error", in:Bundle.aiiResourceBundle(), compatibleWith: nil)!)
    }


    //MARK:- 按钮不同状态的图片设置
    public func setBackGgImage(image: UIImage) {
        _ = btns.map { (btn) -> Void in
            btn.setBackgroundImage(image, for: .normal)
            btn.setBackgroundImage(image, for: .highlighted)
        }
    }

    public func setNormalImage(image: UIImage) {
        _ = btns.map({ (btn) -> Void in
            btn.setImage(image, for: .normal)
        })
    }

    public func setSelectedImage(image: UIImage) {
        _ = btns.map({ (btn) -> Void in
            btn.setImage(image, for: .selected)
        })
    }

    public func setHighlightedImage(image: UIImage) {
        _ = btns.map({ (btn) -> Void in
            btn.setImage(image, for: .highlighted)
        })
    }

    //MARK:- 错误的时候 执行的方法
    public  func errorShow(withDuration duration: TimeInterval, completion: (() -> Void)?) {
        drawingLayer.strokeColor = errorLineColor.cgColor
        for obj in selectPoints {
            obj.isSelected = false
            obj.isHighlighted = true
        }
        draw()
        DispatchQueue.main.asyncAfter(deadline: .now() + duration) {
            if !self.isTracking || !self.isTouchInside {
                self.clean()
            }
            if completion != nil {
                completion!()
            }
        }
    }

    //MARK:- 验证完成后清理layer
    public func clean() {
        for obj in btns{
            layer.insertSublayer(obj.layer, below: drawingLayer)
            obj.isHighlighted = false
            obj.isSelected = false
        }
        drawingLayer.strokeColor = lineColor.cgColor
        drawingLayer.path = nil
        selectPoints.removeAll()
    }

    public func clean(afterDuration duration: TimeInterval, completion : (() -> Void)?) {
        DispatchQueue.main.asyncAfter(deadline: .now() + duration) {
            if !self.isTracking || !self.isTouchInside {
                self.clean()
            }
            if completion != nil {
                completion!()
            }
        }
    }

    //MARK:- 以下方法不需要关注
    override public func layoutSubviews() {
        super.layoutSubviews()
        let w: CGFloat = (bounds.size.width - contentInset.left - itemSize.width / 2 - itemSize.width / 2 - contentInset.right) / 2
        let h: CGFloat = (bounds.size.height - contentInset.top - itemSize.height / 2 - itemSize.height / 2 - contentInset.bottom) / 2
        for (idx, obj) in btns.enumerated(){
            let row: Int = idx / 3
            let col: Int = idx % 3
            obj.bounds = CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(itemSize.width), height: CGFloat(itemSize.height))
            obj.center = CGPoint(x: CGFloat(contentInset.left + itemSize.width / 2 + w * CGFloat(col)), y: CGFloat(contentInset.top + itemSize.height / 2 + h * CGFloat(row)))
        }
    }

    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    //MARK: - UIControl
    override public func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
        clean()
        var shouldBegin: Bool = false
        for obj in btns{
            if obj.frame.contains(touch.location(in: self)) {
                shouldBegin = true
                selectPoints.append(obj)
                obj.isSelected = true
                layer.insertSublayer(obj.layer, above: drawingLayer)
                self.draw()
                break
            }
        }
        return shouldBegin
    }

    override public func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
        fingerPoint = NSValue(cgPoint: touch.location(in: self))
        for obj in btns{
            if obj.frame.contains(touch.location(in: self)) {
                if !selectPoints.contains(obj) {
                    selectPoints.append(obj)
                    obj.isSelected = true
                    layer.insertSublayer(obj.layer, above: drawingLayer)
                }
            }
        }
        draw()
        sendActions(for: .valueChanged)
        return true
    }

    override public func endTracking(_ touch: UITouch?, with event: UIEvent?) {
        fingerPoint = nil
        draw()
        if (didFinishDrawing != nil) {
            guard let tags: [Int] = (selectPoints as NSArray).value(forKeyPath: "tag") as? [Int] else { return }

            let pwd = tags.reduce("", {
                $0 + String($1)
            })
            didFinishDrawing!(self, pwd)
        }
    }

    func draw() {
        if selectPoints.count > 0{
            let path = UIBezierPath()
            let p0: CGPoint = selectPoints.first!.center
            path.move(to: p0)
            for (idx, obj) in selectPoints.enumerated(){
                if idx != 0 {
                    path.addLine(to: obj.center)
                }
            }
            if fingerPoint != nil {
                path.addLine(to: (fingerPoint?.cgPointValue)!)
            }
            drawingLayer.path = path.cgPath
        }
        else {
            drawingLayer.path = nil
        }
    }
}


public enum LockType : Int {
    case create  //创建
    case confirm //确认
    case verify  //验证
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值