[优化]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()
        }
    }
}

  

时间: 2024-08-26 19:05:30

[优化]Swift 简简单单实现手机九宫格手势密码 解锁的相关文章

Swift 简简单单实现手机九宫格手势密码解锁

大家可以看到我之前的文章[HTML5 Canvas简简单单实现手机九宫格手势密码解锁] 本文是使用苹果语言对其进行了移植 颜色配色是拾取的支付宝的颜色 本文的目的说明:语言是想通的  只要思路在 语言只是手段而已 这是本人自学swift一个礼拜 然后花了三个小时写出来的肯定会有不规范的地方 因为思路比较简单 大家可以参考 javascript 版本 废话不多说先上效果 (对了 大家如果能在转载的地方注明出处的话 那就是极好的 http://www.cnblogs.com/zzzzz/p/swif

HTML5 Canvas简简单单实现手机九宫格手势密码解锁

原文:HTML5 Canvas简简单单实现手机九宫格手势密码解锁 早上花了一个半小时写了一个基于HTML Canvas的手势解锁,主要是为了好玩,可能以后会用到. 思路:根据配置计算出九个点的位置,存入一个数组,当然存入数组的顺序的索引是: 第一行:0   1  2   第二行:3  4  5 第三行:6  7  8 然后就根据这个坐标数组去绘制九个点 再则我们需要一个保存选中点的数组,每当touchmove事件就判断当前触摸点和那个点的距离小于圆的半径  如果为真的话 那么就添加进入选中点的数

[IOS]Swift 遍历预制的本地资源文件

我事先放了一堆svg文件,但是我是批量使用的,想要直接遍历他们加入到一个list中来,那我直接就遍历他们的名称,把他们的名字组成一个array. var ss:NSString = NSBundle.mainBundle().resourcePath!//6.0.1修改了要求感叹号 println(ss) var nsfilemange = NSFileManager.defaultManager() var filelist=NSArray.alloc() filelist=nsfileman

九宫格手势密码

公司项目中需要做一个手势密码,效果如图: 上面小的手势图与下面大的联动,效果: 由于没有合用的第三方,就只好自己写了一个,根据需求,下面的每连上一个点就需要通知上方小密码盘,做相应改变,并且绘制完成后,需要获取手势密码的内容,所以设计了如下接口: public interface GesturesPasswordListener { /** * * @param list 绘制完成的密码 */ void getGesturesPassword(List<Integer> list); /**

Html5实现手机九宫格密码解锁功能

HTML5真的是很强大,前端时间看到一个canvas实现九宫格的密码解锁.今天抽出时间模仿了一个,特定分享一下! 效果截图如下: 效果看起来还不错吧! 源码如下: <!DOCTYPE html> <html> <head lang="zh-CN"> <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"

iOS10收集IDFA,植入第三方广告[终结]--ADMob

[PS: 前段时间,公司做ASO推广,需要在应用中收集IDFA值,跟广告平台做交互!于是有了这个需求--] 1.首先,考虑了一下情况(自己懒 -_-#),就直接在首页上写了一个Banner,循环加载广告[都是自己公司的一些广告消息]: 然后,就过了审核![万事大吉] 这里打个小广告,自己简单封装了一个MBAdBanner小框架,已经上传到GitHub上了. 2.然后,最近更新版本的时候,由于收集IDFA而没有实质性广告就杯具了.果断的大大红色Reject! DONE: 加入了一些其他平台的广告(

iOS第三方库汇总[转载]

iOS第三方库汇总[转载] 字数2179 阅读334 评论0 喜欢29 简介 此文用于总结,本人使用过或者收藏过的Github第三方类库,以便日后查阅,也便他人借鉴. 资料整理中不定期更新... 开源项目 CodeHub browse and maintain your GitHub repositories on any iOS device! Open-Source iOS Apps 开源iOS apps列表 APP相关 iVersion 提示版本更新 BonMot 字体相关的库,设置字体样

[翻译]The Neophyte&#39;s Guide to Scala Part 12: Type Classes

The Neophyte's Guide to Scala Part 12: Type Classes 过去的两周我们讨论了一些使我们保持DRY和灵活性的函数式编程技术,特别是函数组合,partial function的应用,以及currying.接下来,我将会继续讨论如何使你的代码尽可能的灵活. 但是,这次我们将不会讨论怎么使用函数作为一等对象来达到这个目的,而是使用类型系统,这次它不是阻碍着我们,而是使得我们的代码更灵活:你将会学到关于 type classes 的知识. 你可能会觉得这是一

[转]useradd 与adduser的区别

转自:Deit_Aaron的专栏 添加用户:useradd -m 用户名  然后设置密码  passwd 用户名 删除用户:userdel  -r  用户名 1. 在root权限下,useradd只是创建了一个用户名,如 (useradd  +用户名 ),它并没有在/home目录下创建同名文件夹,也没有创建密码,因此利用这个用户登录系统,是登录不了的,为了避免这样的情况出现,可以用 (useradd -m +用户名)的方式创建,它会在/home目录下创建同名文件夹,然后利用( passwd +