[优化]Swift 简简单单实现手机九宫格手势密码 解锁

我去 为毛这篇文章会被移除首页 技术含量还是有点的   如果在此被移除  那就果断离开园子了

 

之前的文章 Swift 简简单单实现手机九宫格手势密码解锁

1.对之前的绘制线条的方法进行优化 之前是遍历选中点的集合分别的在点之间绘制线条

  改进之后使用系统的API一口气将线条绘制出来

2.增加密码错误情况下想某宝一样红色提示和三角形状的路线指示如下图所示

3.遇到的难点主要是三角形的绘制 和 旋转角度的功能 原理就不多说了 真相见代码

转载需要注明出处 http://www.cnblogs.com/zzzzz/

暂时代码中每次输入都是错误的,相关功能修改一下就可以了

效果图如下:

技术分享技术分享

 

给Controller绑定View

override func viewDidLoad() {
      super.viewDidLoad()
      // Do any additional setup after loading the view, typically from a nib.
      self.view = NineCellLockView(frame: CGRectZero)
  }

下面是具体的View 的代码

import UIKit

class NineCellLockView: UIView {
    
    var fingerPoint:CGPoint = CGPoint()
    var linePointointCollection:Array<CGPoint> = Array<CGPoint>()
    var ninePointCollection:Array<CGPoint> = Array<CGPoint>()
    
    var selectPointIndexCollection:Array<Int> = Array<Int>()
    
    var pswIsRight:Bool = true
    var circleRadius:CGFloat = 28
    var littleCircleRadius:CGFloat = 10
    var circleCenterDistance:CGFloat = 96
    var firstCirclePointX:CGFloat = 96
    var firstCirclePointY:CGFloat = 200
    
    func FillNinePointCollection()
    {
        for row in 0...2
        {
            for column in 0...2
            {
                let tempX:CGFloat = CGFloat(column)*self.circleCenterDistance + self.firstCirclePointX
                let tempY:CGFloat = CGFloat(row)*self.circleCenterDistance + self.firstCirclePointY
                self.ninePointCollection.append(CGPoint(x: tempX,y:tempY))
            }
        }
    }
    
    
    func drawCicle(centerPoint:CGPoint,index:Int,context:CGContext)
    {
        CGContextSetLineWidth(context, 2.0);
        CGContextAddArc(context, centerPoint.x, centerPoint.y, self.circleRadius, 0.0, CGFloat(M_PI * 2.0), 1)
        let currentIsSelected:Bool = contains(self.selectPointIndexCollection, index)
        
        if(currentIsSelected)
        {
            if(pswIsRight)
            {
            //选中的圆圈的边框颜色不一样
                CGContextSetStrokeColorWithColor(context, UIColor(red: 96/255.0, green: 169/255.0, blue: 252/255.0, alpha: 1).CGColor)
            }else
            {
                CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor)
            }
        
        }else
        {
            CGContextSetStrokeColorWithColor(context,  UIColor(red: 144/255.0, green: 149/255.0, blue: 173/255.0, alpha: 1).CGColor)
        }
        CGContextStrokePath(context)
        //为了遮住圈内的线
        CGContextAddArc(context, centerPoint.x, centerPoint.y, self.circleRadius, 0.0, CGFloat(M_PI * 2.0), 1)
        CGContextSetFillColorWithColor(context,  UIColor(red: 35/255.0, green: 39/255.0, blue: 54/255.0, alpha: 1).CGColor)
        CGContextFillPath(context)

      
        if(currentIsSelected)
        {
            CGContextAddArc(context, centerPoint.x, centerPoint.y, self.littleCircleRadius, 0.0, CGFloat(M_PI * 2.0), 1)
            if(pswIsRight)
            {
                CGContextSetFillColorWithColor(context, UIColor(red: 96/255.0, green: 169/255.0, blue: 252/255.0, alpha: 1).CGColor)
            }else
            {
                CGContextSetFillColorWithColor(context, UIColor.redColor().CGColor)
            }
            
            CGContextFillPath(context)
        }
        
        
        
        
    }
    
    func drawNineCircle(context:CGContext)
    {
        for p in 0...self.ninePointCollection.count-1
        {
            self.drawCicle(self.ninePointCollection[p],index:p,context:context);
        }
        
    }
    
    override init(frame:CGRect)
    {
        super.init(frame:frame)
        //26 29 40
        self.backgroundColor = UIColor(red: 35/255.0, green: 39/255.0, blue: 54/255.0, alpha: 1)
        FillNinePointCollection()
    }
    
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
   
    func DrawLines()
    {
        
        if(self.selectPointIndexCollection.count > 0)
        {
            var bp = UIBezierPath()
            bp.lineWidth  = 1
            bp.lineCapStyle = kCGLineCapRound
            if(pswIsRight)
            {
                UIColor(red: 96/255.0, green: 169/255.0, blue: 252/255.0, alpha: 1).setStroke()
            }else
            {
                UIColor.redColor().setStroke()
            }
            
            for index in 0...self.selectPointIndexCollection.count-1
            {
                let PointIndex = self.selectPointIndexCollection[index]
                
                if(index == 0)
                {
                    bp.moveToPoint(self.ninePointCollection[PointIndex])
                }
                else
                {
                    bp.addLineToPoint(self.ninePointCollection[PointIndex])
                }
            }
            if self.fingerPoint.x != -100
            {
                bp.addLineToPoint(self.fingerPoint)
            }
            bp.stroke()
        }
        
    }
    
    override func drawRect(rect: CGRect) {
        
        var context = UIGraphicsGetCurrentContext();
        self.DrawLines()
        self.drawNineCircle(context)
        self.DrawTriangleWhenPswIsError(context)
        
        
      
    }
    
    
    func GetAngle(p1:CGPoint,p2:CGPoint)->CGFloat
    {
        let Re:CGFloat  = ((atan(CGFloat((p2.y - p1.y) / (p2.x - p1.x)))))
        if p2.x < p1.x
        {
            return  Re - CGFloat(M_PI)
        }
        return Re
    }
    
    //三角形的顶点距离圆心的距离
    var TriangleTopPointDistanceToCircleCenterPoint:CGFloat = 20
    //如果密码密码错误则在选中的圆圈内绘制三角形的路线指示标志
    func DrawTriangleWhenPswIsError(context:CGContext)
    {
        if(pswIsRight)
        {
            return
        }
        if self.selectPointIndexCollection.count <= 1
        {
            return
        }
        
        for index in 0...self.selectPointIndexCollection.count-1
        {
            let preIndex:Int = index - 1
          
            if(preIndex >= 0 )
            {
                let prePointIndex:Int = self.selectPointIndexCollection[preIndex]
                let currentPointIndex:Int = self.selectPointIndexCollection[index]
                var currentPoint :CGPoint  = self.ninePointCollection[currentPointIndex]
                var prePoint:CGPoint  = self.ninePointCollection[prePointIndex]
                
                CGContextSaveGState(context)
                
                CGContextTranslateCTM( context, prePoint.x,prePoint.y )
                CGContextRotateCTM(context, GetAngle(prePoint,p2:currentPoint))
                
                CGContextTranslateCTM( context,0 - prePoint.x,0 - prePoint.y)
                CGContextBeginPath(context)
                CGContextSetFillColorWithColor(context, UIColor.redColor().CGColor)
                //都是绘制在x坐标的右边 上面几行代码是旋转的逻辑
                CGContextMoveToPoint(context,prePoint.x + self.TriangleTopPointDistanceToCircleCenterPoint - 6, prePoint.y - 6)
                CGContextAddLineToPoint(context, prePoint.x + self.TriangleTopPointDistanceToCircleCenterPoint, prePoint.y)
                CGContextAddLineToPoint(context,prePoint.x + self.TriangleTopPointDistanceToCircleCenterPoint - 6, prePoint.y + 6)
                CGContextClosePath(context)
                CGContextFillPath(context)
                
                CGContextRestoreGState(context)

            }
        }
    }
    
    func distanceBetweenTwoPoint(p1:CGPoint,p2:CGPoint)->CGFloat
    {
        return pow(pow((p1.x-p2.x), 2)+pow((p1.y-p2.y), 2), 0.5)
    }
    
    func CircleIsTouchThenPushInSelectPointIndexCollection(fingerPoint:CGPoint)
    {
        
        for index in 0...self.ninePointCollection.count-1
        {
            if(!contains(self.selectPointIndexCollection, index))
            {
                if(self.distanceBetweenTwoPoint(fingerPoint,p2:self.ninePointCollection[index]) <= circleRadius)
                {
                    self.selectPointIndexCollection.append(index);
                }
            }
        }
        
    }
    
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        var t = touches.anyObject() as UITouch
        pswIsRight = true
        self.selectPointIndexCollection.removeAll(keepCapacity: false)
        self.fingerPoint = t.locationInView(self)
        self.CircleIsTouchThenPushInSelectPointIndexCollection(fingerPoint);
        self.setNeedsDisplay()
    }
    
    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
        var t = touches.anyObject() as UITouch
        self.fingerPoint = t.locationInView(self)
        
        self.CircleIsTouchThenPushInSelectPointIndexCollection(self.fingerPoint);
        
        self.setNeedsDisplay()
    }
    
    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
        self.fingerPoint.x = -100
        self.setNeedsDisplay()
        pswIsRight = false //模拟密码错误
        if(self.selectPointIndexCollection.count>0)
        {
            var ReStr:String = ""
            for index in 0...self.selectPointIndexCollection.count-1
            {
                ReStr += String(self.selectPointIndexCollection[index]) + ","
            }
            
            let alertV = UIAlertView(title: "您的结果", message: ReStr, delegate: nil, cancelButtonTitle: "我知道了")
            alertV.show()
        }
    }
}

  

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。