【Swift3】手势密码

作者: 亲爱的大倩倩 | 来源:发表于2017-05-15 15:07 被阅读101次

    项目说明

    初次打开设置并确认手势密码,超过五次后重置
    在设置中修改手势密码
    APP退至后台10S后需要手势密码解锁进入

    思路

    • window的根视图是mainVC,在mainVC中设置完主控制器后,添加gestureView(手势密码)
    • 在gestureView中
      通过UIButton,UIBezierPath,数组和变量实现手势密码绘制
      手势按钮即9个button,上面有个messageLabel
    非修改手势密码思路

    不移除self.path所有点就会这样


    将按钮颜色去掉会发现,当path.move时,当前点不会多余线,但当path.addLine时,则结束时会记录下你划过的方向


    修改手势密码思路
    gestureView主要代码如下
    import UIKit
    
    class GestureView: UIView
    {
        //初次登陆时候的最多输入次数
        var inputCount:Int = 0
        //控制是否初次登陆
        var isFirst:Bool = true
        //控制是否修改密码
        var isChangeGestures:Bool = false
        
        //路径
        var path:UIBezierPath = UIBezierPath()
        //存储已经路过的点
        var pointsArray = [CGPoint]()
        //当前手指所在点
        var fingurePoint:CGPoint!
        //密码存储
        var passwordArray = [Int]()
        
        
        //MARK: - Override
        override init(frame: CGRect)
        {
            super.init(frame: frame)
            layoutUI()
        }
        
        required init?(coder aDecoder: NSCoder)
        {
            fatalError("init(coder:) has not been implemented")
        }
        
        init(frame: CGRect,changeGestures:Bool)
        {
            super.init(frame: frame)
            isChangeGestures = changeGestures
            layoutUI()
        }
        
        
        //MARK: - 懒加载
        lazy var messageLabel : UILabel =
        {
            let label = UILabel()
            label.textColor = UIColor.darkGray
            label.textAlignment = NSTextAlignment.center
            return label
        }()
        
        //MARK: - UI
        func layoutUI()
        {
            self.backgroundColor = UIColor.white
            //添加提示框
            addSubview(messageLabel)
            messageLabel.frame = CGRect(x: 0, y: 100, width: ScreenWidth, height: 50)
            //添加手势密码
            gesturePasswordUI()
            //设置path
            path.lineWidth = 2
            
            //是否修改密码
            if isChangeGestures
            {
                print("这是修改密码界面")
                UserDefaults.standard.removeObject(forKey: "newPassWord")
                messageLabel.text = "请输入新的手势密码"
                
            }
            else
            {
                print("不是修改密码界面")
                //本地密码
                let passWord = UserDefaults.standard.value(forKey: "passWord")
                if(passWord != nil)
                {
                    isFirst = false
                    messageLabel.text = "确认手势密码"
                }
                else
                {
                    messageLabel.text = "请创建手势密码"
                }
            }
            
    
        }
        
        func gesturePasswordUI()
        {
            //画密码
            let width:CGFloat = 60.0
            let height:CGFloat = width
            var x:CGFloat = 0
            var y:CGFloat = 0
            //计算空隙
            let spaceWidth = (ScreenWidth - 3 * width) / 4
            let spaceHeight = (ScreenHeight - 3 * height) / 4
            for index in 0..<9
            {
                //计算当前所在行
                let row = index % 3
                let line = index / 3
                //计算坐标
                x = CGFloat(row) * width + CGFloat(row + 1) * spaceWidth
                y = CGFloat(100 * line) + spaceHeight * 2
                let button = NumberButton(frame: CGRect(x: x, y: y, width: width, height: height))
                button.tag = index
                addSubview(button)
            }
        }
    
        
        
        //MARK: - Other Functions
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
        {
            //每次点击移除所有存储过的点,重新统计
            pointsArray.removeAll()
            touchChanged(touch: touches.first!)
        }
        
        
        override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
        {
            touchChanged(touch: touches.first!)
        }
        
        func touchChanged(touch:UITouch)
        {
            let point = touch.location(in: self)
            fingurePoint = point
            for button in subviews
            {
                if button.isKind(of: NumberButton.self) && !pointsArray.contains(button.center) && button.frame.contains(fingurePoint)
                {
                    //记录已经走过的点
                    passwordArray.append(button.tag)
                    //记录密码
                    pointsArray.append(button.center)
                    //设置按钮的背景色
                    button.backgroundColor = UIColor.hexStringToColor(hexString: ColorOfBlueColor)
                }
                
            }
            //会调用draw 方法
            setNeedsDisplay()
        }
        
        override func draw(_ rect: CGRect)
        {
            self.path.removeAllPoints()
            for (index,point) in pointsArray.enumerated()
            {
                if index == 0
                {
                    path.move(to: point)
                }
                else
                {
                    path.addLine(to: point)
                }
                
            }
            //让画线跟随手指
            if self.fingurePoint != CGPoint.zero && self.pointsArray.count > 0
            {
                path.addLine(to: self.fingurePoint)
            }
            
            //设置线的颜色
            let color = UIColor.hexStringToColor(hexString: ColorOfBlueColor)
            color.set()
            path.stroke()
        }
        
        
        //松手的时候调用
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
        {
            if(passwordArray as NSArray).count == 0
            {
                return
            }
            inputCount += 1
            
            //本地存储
            let passWord = UserDefaults.standard.value(forKey: "passWord")
            let newPassWord = UserDefaults.standard.value(forKey: "newPassWord")
            //修改密码界面
            if isChangeGestures
            {
                if(newPassWord != nil )
                {
                    if Tools().passwordString(array: passwordArray as NSArray) == Tools().passwordString(array: newPassWord as! NSArray)
                    {
                        messageLabel.text = "设置成功"
                        isHidden = true
                        UserDefaults.standard.set(passwordArray, forKey: "passWord")
                    }
                    else
                    {
                        if inputCount < 5
                        {
                            messageLabel.text = "输入错误,还可以输入\(5 - inputCount)次"
                        }
                        else
                        {
                            messageLabel.text = "请重置手势密码"
                            inputCount = 0
                            UserDefaults.standard.removeObject(forKey: "newPassWord")
                        }
                        
                    }
    
                }
                else//初次储存新密码
                {
                    UserDefaults.standard.set(passwordArray, forKey: "newPassWord")
                }
                
            }
            //非修改密码界面
            else
            {
                //初次登陆,五次设置密码的机会
                if isFirst
                {
                    if(passWord != nil && (passWord as! NSArray).count > 0)
                    {
                        if Tools().passwordString(array: passwordArray as NSArray) == Tools().passwordString(array: passWord as! NSArray)
                        {
                            messageLabel.text = "设置成功"
                            isHidden = true
                        }
                        else
                        {
                            if inputCount < 5
                            {
                                messageLabel.text = "输入错误,还可以输入\(5 - inputCount)次"
                            }
                            else
                            {
                                messageLabel.text = "请重置手势密码"
                                inputCount = 0
                                UserDefaults.standard.removeObject(forKey: "passWord")
                            }
                            
                        }
                    }
                    else//初次存储
                    {
                        messageLabel.text = "确认手势密码"
                        UserDefaults.standard.set(passwordArray, forKey: "passWord")
                    }
                    
                }
                else//非初次登陆,不可重置密码,只能一直输入
                {
                    if Tools().passwordString(array: passwordArray as NSArray) == Tools().passwordString(array: passWord as! NSArray)
                    {
                        isHidden = true
                    }
                    else
                    {
                        messageLabel.text = "输入错误"
                        
                    }
                    
                }
            }
            
            //移除所有的记录
            pointsArray.removeAll()
            passwordArray.removeAll()
            path.removeAllPoints()
            setNeedsDisplay()
            fingurePoint = CGPoint.zero
            
            //清除所有按钮的选中状态
            for button in subviews
            {
                if button.isKind(of: NumberButton.self)
                {
                    button.backgroundColor  =  UIColor.clear
                }
            }
            
        }
    }
    
    
    APP退至后台10S后需要手势密码解锁进入

    当APP进入后台时记录当前时间
    当APP进入前台时记录当前时间
    如果这两个时间差大于10S,则显示gestureView界面,并且设置gestureView的isFirst等于false(证明不是初次设置),并且设置gestureView的messageLabel显示"确认手势密码"

        //进入后台
        func applicationDidEnterBackground(_ application: UIApplication)
        {
            let now = Date()
            let timeInterval:TimeInterval = now.timeIntervalSince1970
            let timeStamp = Int(timeInterval)
            UserDefaults.standard.set(timeStamp, forKey: "currentTime")
        }
        
        //进入前台
        func applicationWillEnterForeground(_ application: UIApplication)
        {
            let now = Date()
            let timeInterval:TimeInterval = now.timeIntervalSince1970
            let timeStamp = Int(timeInterval)
            let currentTime = UserDefaults.standard.value(forKey: "currentTime")
            if (timeStamp - (currentTime as! Int)) > 10
            {
                //超过10S则显示手势密码
                mainVC.gestureView.isHidden = false
                mainVC.gestureView.isFirst = false
                mainVC.gestureView.messageLabel.text = "确认手势密码"
            }
        }
    
    

    但是因为设置的二级界面调用了gestureView,若此时APP退至后台,再回前台,指纹解锁后进来还是指纹解锁,用户体验不好,所以应该监听APP的进入后台的方法,当程序进入后台的时候,我们应该让设置界面的gestureView移除

    在基类中添加消息,并且实现消息
    import UIKit
    
    class BaseViewController: UIViewController
    {
    
        override func viewDidLoad()
        {
            super.viewDidLoad()
            //监听程序挂起消息
            NotificationCenter.default.addObserver(self, selector: #selector(test), name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
        }
        
        func test()
        {
            print("后台挂起")
        }
    
    }
    
    在设置控制器中重写消息的实现方法,如果APP退出后台了,会自己调用
        override func test()
        {
            gestureView?.removeFromSuperview()
        }
    

    Demo地址:
    https://github.com/CarolineQian/FQGesturesPassword

    相关文章

      网友评论

        本文标题:【Swift3】手势密码

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