爱程序网

Swift实现手势解锁

来源: 阅读:

按钮是根据屏幕大小自动布局,所以不会因为设备不同导致错位
数据库操作是GitHub上的SQLiteDB

下面是Storyboard的设计图

 

 

 

 

 

 

 

下面是实现的代码

//
//  ViewController.swift
//  
//
//  Created by XWJACK on 15/12/15.
//  Copyright © 2015年 XWJACK. All rights reserved.
//

import UIKit

class ViewController: UIViewController,SegueDelegate {
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        //self.view = GestureUnLock(frame: CGRectZero)
        let GestureUnLockview:GestureUnLock = GestureUnLock(frame: CGRectZero)
        GestureUnLockview.seguedelegate = self
        self.view = GestureUnLockview
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    //跳转
    func segue(){
        self.performSegueWithIdentifier("ToMainSegue", sender: self)
    }
    //传值
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    }
    
    deinit{
        print("ViewController End")
    }
}

 

//
//  ContainTableViewCell.swift
//  
//
//  Created by XWJACK on 12/24/15.
//  Copyright © 2015 XWJACK. All rights reserved.
//

import UIKit

class ContainTableViewCell: UITableViewCell {
    @IBOutlet weak var Contain: UILabel!
    @IBOutlet weak var Username: UILabel!
    @IBOutlet weak var Password: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        // Configure the view for the selected state
    }

}
//
//  EditViewController.swift
//  
//
//  Created by XWJACK on 12/26/15.
//  Copyright © 2015 XWJACK. All rights reserved.
//

import UIKit

class EditViewController: UIViewController {

    @IBOutlet weak var Contain: UITextField!
    @IBOutlet weak var Username: UITextField!
    @IBOutlet weak var Password: UITextField!
    
    var oldContain:String?
    var oldUsername:String?
    var oldPassword:String?
    
    //true为add,false为edit
    var editOrAdd:Bool = true
    var block:BlockComplateHandle?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.whiteColor()
        Contain?.text = oldContain
        Username?.text = oldUsername
        Password?.text = oldPassword
        // Do any additional setup after loading the view.
    }
    @IBAction func save(sender: UIBarButtonItem) {
        Password.resignFirstResponder()
        let tempContain:String? = Contain.text
        let tempUsername:String? = Username.text
        let tempPassword:String? = Password.text
        
        if tempContain != ""{//判断Contain是否为空
            for var temp in CellContain {//判断有没有重复
                let value = temp["Contain"] as? String
                if value == tempContain{
                    let alert = UIAlertView(title: "Error", message: "Repeat Contain", delegate: self, cancelButtonTitle: "OK")
                    alert.show()
                    return
                }
            }
            block?(contain: tempContain!, username: tempUsername!, password: tempPassword!)
            self.navigationController?.popViewControllerAnimated(true)
        }else{
            let alert = UIAlertView(title: "Error", message: "No Contain", delegate: self, cancelButtonTitle: "OK")
            alert.show()
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    //block回调
    func passValueUseBlock(myblock:BlockComplateHandle){
        block = myblock
    }
    //隐藏键盘
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.view.endEditing(true)
    }
    
    deinit{
        print("EditViewController End")
    }
    
    
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */
}
//
//  MainTableViewController.swift
//  
//
//  Created by XWJACK on 12/23/15.
//  Copyright © 2015 XWJACK. All rights reserved.
//

import UIKit

//cell的内容
var CellContain:[[String:AnyObject]] = []

class MainTableViewController: UITableViewController {

    
    var selectIndex:NSIndexPath?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false
        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        //self.navigationItem.leftBarButtonItem = self.editButtonItem()
        let dboperator = DataOperate()
        CellContain = dboperator.ReadAllFromDB()
        //print(CellContain)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    // MARK: - Table view data source
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return CellContain.count
    }
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("contain", forIndexPath: indexPath) as! ContainTableViewCell
        cell.Contain.text = CellContain[indexPath.row]["Contain"] as? String
        cell.Username.text = CellContain[indexPath.row]["Username"] as? String
        cell.Password.text = CellContain[indexPath.row]["Password"] as? String
        cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
        // Configure the cell...
        return cell
    }
    /*
    // Override to support conditional editing of the table view.
    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return true
    }
    */
    // Override to support editing the table view.
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            // Delete the row from the data source
            //数据库删除
            let PrimaryKey = CellContain[indexPath.row]["Contain"] as? String
            let delete = DataOperate()
            if let temp = PrimaryKey{
                delete.DeleteRow(temp)
            }
            //数据删除
            CellContain.removeAtIndex(indexPath.row)
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Left)
        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
    //编辑
    func editContain(contain contain: String?, username: String?, password: String?) {
        let OldContain = CellContain[selectIndex!.row]["Contain"] as? String
        CellContain[selectIndex!.row]["Contain"] = contain
        CellContain[selectIndex!.row]["Username"] = username
        CellContain[selectIndex!.row]["Password"] = password
        
        let update = DataOperate()
        update.EditRow(PrimaryKey: OldContain!, Contain: contain!, Username: username!, Password: password!)
        self.tableView.reloadData()
    }
    //添加
    func addContain(contain contain: String?, username: String?, password: String?){
        CellContain.append(["Contain":"\(contain!)","Username":"\(username!)","Password":"\(password!)"])
        
        let insert = DataOperate()
        insert.AddRow(PrimaryKey: contain!, Username: username!, Password: password!)
        self.tableView.reloadData()
    }
    /*
    // Override to support rearranging the table view.
    override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {

    }
    */

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return false if you do not want the item to be re-orderable.
        return true
    }
    */
    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
        if segue.identifier == "AddSegue" {
            let destination = segue.destinationViewController as? EditViewController
            if let temp = destination {
                temp.editOrAdd = true
                
                temp.passValueUseBlock{(contain: String, username: String, password: String) -> Void in
                    self.addContain(contain: contain, username: username, password: password)
                }
            }
        }
        
        
        if segue.identifier == "EditSegue" {
            selectIndex = self.tableView.indexPathForSelectedRow
            let destination = segue.destinationViewController as? EditViewController
            if let temp = destination {
                if let index = selectIndex{
                    temp.oldContain = CellContain[index.row]["Contain"] as? String
                    temp.oldUsername = CellContain[index.row]["Username"] as? String
                    temp.oldPassword = CellContain[index.row]["Password"] as? String
                    temp.editOrAdd = false
                    temp.passValueUseBlock{(contain: String, username: String, password: String) -> Void in
                        self.editContain(contain: contain, username: username, password: password)
                    }
                }
            }
        }
    }


}
//
//  SettingViewController.swift
//  
//
//  Created by XWJACK on 12/31/15.
//  Copyright © 2015 XWJACK. All rights reserved.
//

import UIKit

class SettingViewController: UIViewController,SegueDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let GestureUnLockview:GestureUnLock = GestureUnLock(frame: CGRectZero)
        GestureUnLockview.Change = false
        GestureUnLockview.seguedelegate = self
        self.view = GestureUnLockview
        
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    //跳转
    func segue(){
        let alert = UIAlertView(title: "Success", message: "Change Password Success", delegate: nil, cancelButtonTitle: "OK")
        alert.show()
        self.navigationController?.popViewControllerAnimated(true)
    }
    
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}
//
//  NavigationController.swift
//  
//
//  Created by XWJACK on 12/27/15.
//  Copyright © 2015 XWJACK. All rights reserved.
//

import UIKit

class NavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}
//
//  DataBaseOperate.swift
//  
//
//  Created by XWJACK on 12/23/15.
//  Copyright © 2015 XWJACK All rights reserved.
//

import Foundation

//数据库实例
let db = SQLiteDB.sharedInstance()

//验证登陆
class Verify{
    func verify(password:String) -> Bool{
        let data = db.query("select * from admin")
        if data.count > 0{
            for temp in data{
                let LoginPassword = temp["LoginPassword"] as? String
                if LoginPassword == password {
                    return true
                }else{
                    return false
                }
            }
        }else{
            return false
        }
        return false
    }
}

//修改密码
class ChangePassword{
    class func ChangePassword(password:String) -> Bool{
        let sql = "update admin set LoginPassword='\(password)'"
        if db.execute(sql) == 1{
            return true
        }else{
            return false
        }
    }
}

//登陆数据操作
class LoginPasswordOperate{
    //创建登陆表
    func CreateTable(){
        //如果表不存在就创建表
        let sql = "create table if not exists admin(LoginUser primary key,LoginPassword text)"
        db.execute(sql)
    }
    //将密码写入数据库
    func WriteDB(password:String){
        let user = "admin"
        let sql = "insert into admin(LoginUser,LoginPassword) values('\(user)','\(password)')"
        db.execute(sql)
    }
}

//数据操作
class DataOperate{
    //创建表
    func CreateTable(){
        let sql = "create table if not exists contain(Contain primary key,Username text,Password text)"
        db.execute(sql)
    }
    //查找全部内容
    func ReadAllFromDB() -> [[String:AnyObject]]{
        let sql = "select * from contain"
        return db.query(sql)
    }
    //删除数据
    func DeleteRow(PrimaryKey:String){
        let sql = "delete from contain where Contain='\(PrimaryKey)'"
        db.execute(sql)
    }
    //添加数据
    func AddRow(PrimaryKey Contain:String, Username:String, Password:String){
        let sql = "insert into contain values('\(Contain)','\(Username)','\(Password)')"
        db.execute(sql)
    }
    //更新数据
    func EditRow(PrimaryKey OldContain:String, Contain:String, Username:String, Password:String){
        let sql = "update contain set Contain='\(Contain)',Username='\(Username)',Password='\(Password)' where Contain='\(OldContain)'"
        db.execute(sql)
    }
}
//
//  Login.swift
//  
//
//  Created by XWJACK on 15/12/21.
//  Copyright © 2015年 XWJACK. All rights reserved.
//

import UIKit
//锁屏
class GestureUnLock: UIView {
    
    enum StatusLine{//线条状态
        case defaultLine
        case rightLine
        case wrongLine
    }
    //定义按钮集合
    var button:[UIButton] = [UIButton]()
    //屏幕大小
    let screen:UIScreen = UIScreen.mainScreen()
    var size:CGRect = CGRect()
    //默认按钮图片
    let DefaultBackgroundImage:UIImage? = UIImage(named: "gp_gray@3x")
    //触摸后按钮前图
    let TouchImage:UIImage? = UIImage(named: "gp_bluedot@3x")
    //触摸后按钮背景图
    let TouchBackgroundImage:UIImage? = UIImage(named: "gp_blue@3x")
    //正确按钮前图
    let RightImage:UIImage? = UIImage(named: "gp_greendot@3x")
    //正确按钮背景图
    let RightBackgroundImage:UIImage? = UIImage(named: "gp_green@3x")
    //错误按钮前图
    let WrongImage:UIImage? = UIImage(named: "gp_reddot@3x")
    //错误按钮背景图
    let WrongBackgroundImage:UIImage? = UIImage(named: "gp_red@3x")
    //九个点的位置
    var pozition:[CGRect] = Array<CGRect>(count: 9, repeatedValue: CGRect(x: 0.0, y: 0.0, width: 0.0, height: 0.0))
    //九个点的圆心位置
    var CenterPozition:[CGPoint] = Array<CGPoint>(count: 9, repeatedValue: CGPoint(x: 0.0, y: 0.0))
    //手指的坐标
    var fingerPoint:CGPoint = CGPoint()
    //收集触摸的点
    var selectPointIndexCollection:[Int] = Array<Int>()
    //正确还是错误
    var status:Bool? = nil
    //判断是否是修改密码true表示是登陆,false表示是修改密码
    var Change:Bool = true
    //代理,用于跳转
    //weak为弱引用,不会造成内存泄露
    weak var seguedelegate:SegueDelegate?
    
    
    override init(frame:CGRect){
        super.init(frame:frame)
        //26 29 40
        self.backgroundColor = UIColor(red: 62/255.0, green: 63/255.0, blue: 67/255.0, alpha: 1)
        CreateButton()
    }
    
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func drawRect(rect: CGRect) {
        // Drawing code
        var type = StatusLine.defaultLine
        if status == true{
            type = StatusLine.rightLine
        }else if status == false{
            type = StatusLine.wrongLine
        }
        if selectPointIndexCollection.count > 0 {
            for index in 0...self.selectPointIndexCollection.count - 1 {
                let nextIndex = index + 1
                if nextIndex < self.selectPointIndexCollection.count{
                    let firstPointIndex = self.selectPointIndexCollection[index]
                    let secondPointIndex = self.selectPointIndexCollection[nextIndex]
                    drawLine(point1: CenterPozition[firstPointIndex - 1], point2: CenterPozition[secondPointIndex - 1],statusline: type)
                }
            }
            if fingerPoint.x != -100{//去掉最后的一条线
                let lastPoint = CenterPozition[self.selectPointIndexCollection[self.selectPointIndexCollection.count - 1] - 1]
                drawLine(point1: lastPoint, point2: fingerPoint,statusline: type)
            }
        }
        //CreateButton()
        CreateTitle()
    }
    
    //画线
    func drawLine(point1 point1:CGPoint, point2:CGPoint, statusline:StatusLine){
        let bp = UIBezierPath()
        
        switch statusline{
        case StatusLine.defaultLine:
            UIColor(red: 107/255.0, green: 179/255.0, blue: 244/255.0, alpha: 1).setStroke()
        case StatusLine.rightLine:
            UIColor(red: 126/255.0, green: 211/255.0, blue: 113/255.0, alpha: 1).setStroke()
        case StatusLine.wrongLine:
            UIColor(red: 189/255.0, green: 60/255.0, blue: 53/255.0, alpha: 1).setStroke()
        }
        bp.lineWidth = 3
        bp.moveToPoint(point1)
        bp.addLineToPoint(point2)
        bp.stroke()
    }
    //判断触摸点是否在button内
    func IsFingerInButtonThenCollection(finger:CGPoint){
        for index in 0...8 {
            if !selectPointIndexCollection.contains(index + 1) {//判断是否已经被选中
                if CGRectContainsPoint(pozition[index], finger) {//判断是否在button中
                    self.selectPointIndexCollection.append(index + 1)
                    self.changeButtonImage(self.button[index])
                }
            }
        }
    }
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let t = touches.first
        self.fingerPoint = t!.locationInView(self)
        IsFingerInButtonThenCollection(fingerPoint)
        self.setNeedsDisplay()
    }
    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let t = touches.first
        self.fingerPoint = t!.locationInView(self)
        IsFingerInButtonThenCollection(fingerPoint)
        self.setNeedsDisplay()
    }
    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        var password = ""
        self.fingerPoint.x = -100
        if selectPointIndexCollection.count < 3 && selectPointIndexCollection.count != 0{//密码少于三位
            let alert = UIAlertView(title: "提示", message: "密码少于3位", delegate: self, cancelButtonTitle: "知道了")
            alert.show()
        }else if selectPointIndexCollection.count == 0{//没有选中任何的按钮
            
        }else{
            for index in selectPointIndexCollection {//得到密码
                password += "\(index)"
            }
            if Change{//登陆
                let verify = Verify()
                if verify.verify(password){//正确就跳转
                    changeButtonImageRight()
                    status = true
                    self.setNeedsDisplay()
                    if let delegate = seguedelegate{
                        delegate.segue()
                    }
                }else{
                    changeButtonImageWrong()
                    status = false
                }
            }else{//修改密码
                if ChangePassword.ChangePassword(password) {
                    if let delegate = seguedelegate{
                        delegate.segue()
                    }
                }
            }
        }
        NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "goDefault", userInfo: nil, repeats: false)//延时0.5秒
        self.setNeedsDisplay()
    }
    
    //返回程序初始状态
    func goDefault(){
        selectPointIndexCollection = []
        goBackDefaultButtonImage()
        status = nil
        self.setNeedsDisplay()
    }
    func CreateTitle(){
        let lable = UILabel()
        lable.frame = CGRect(x: pozition[1].origin.x, y: pozition[1].origin.y - 70, width: pozition[1].width, height: 30.0)
        lable.textColor = UIColor(red: 220/255.0, green: 217/255.0, blue: 222/255.0, alpha: 1)
        lable.textAlignment = NSTextAlignment.Center
        if Change{
            lable.text = "Login"
        }else{
            lable.text = "Change"
        }
        self.addSubview(lable)
    }
    //布局按钮
    func CreateButton(){
        size = screen.bounds
        //按钮的半径
        let r = size.width / 10
        //第一个按钮距离屏幕顶部的大小(8 * r是总共按钮的高度,100是按钮距离底部的高度)
        let height:CGFloat = size.height - 100.0 - 8 * r
        for var i = 0; i < 9; i++ {
            switch i {
            case 0,1,2:
                pozition[i] = CGRect(x: 2 * r * CGFloat(i) + CGFloat(i + 1) * r, y: height, width: 2 * r, height: 2 * r)
            case 3,4,5:
                pozition[i] = CGRect(x: 2 * r * CGFloat(i - 3) + CGFloat(i - 3 + 1) * r, y: height + 3 * r, width: 2 * r, height: 2 * r)
            case 6,7,8:
                pozition[i] = CGRect(x: 2 * r * CGFloat(i - 6) + CGFloat(i - 6 + 1) * r, y: height + 6 * r, width: 2 * r, height: 2 * r)
            default:
                break
            }
            CenterPozition[i] = CGPoint(x: pozition[i].origin.x + r,y: pozition[i].origin.y + r)
            button.append(UIButton(frame: pozition[i]))
            button[i].setBackgroundImage(UIImage(named: "gp_gray@3x"), forState: .Normal)
            button[i].userInteractionEnabled = false
            //                button[i]!.addTarget(self, action: Selector("changeImage:"), forControlEvents: UIControlEvents.TouchUpInside)
            self.addSubview(button[i])
        }
    }
    //改变按钮样式
    func changeButtonImage(sender:UIButton){
        sender.setImage(TouchImage, forState: UIControlState.Normal)
        sender.setBackgroundImage(TouchBackgroundImage, forState: UIControlState.Normal)
    }
    //还原全部按钮样式
    func goBackDefaultButtonImage(){
        for index in button {
            index.setImage(nil, forState: UIControlState.Normal)
            index.setBackgroundImage(DefaultBackgroundImage, forState: UIControlState.Normal)
        }
    }
    //密码正确按钮样式
    func changeButtonImageRight(){
        for index in selectPointIndexCollection{
            button[index - 1].setImage(RightImage, forState: UIControlState.Normal)
            button[index - 1].setBackgroundImage(RightBackgroundImage, forState: UIControlState.Normal)
        }
    }
    //密码错误按钮样式
    func changeButtonImageWrong(){
        for index in selectPointIndexCollection{
            button[index - 1].setImage(WrongImage, forState: UIControlState.Normal)
            button[index - 1].setBackgroundImage(WrongBackgroundImage, forState: UIControlState.Normal)
        }
    }
    deinit{
        print("GestureUnLock End")
    }
}
//
//  SegueDelegate.swift
//  
//
//  Created by XWJACK on 12/22/15.
//  Copyright © 2015 XWJACK. All rights reserved.
//

import Foundation

protocol SegueDelegate:NSObjectProtocol{
    func segue()
}

@objc protocol EditDelete{
    func editContain(contain contain:String?, username:String?, password:String?)
    func addContain(contain contain: String?, username: String?, password: String?)
}

typealias BlockComplateHandle = (contain: String, username: String, password: String) -> Void

程序依旧有许多不足的地方,比如在跳转之后内存依旧不降下来,可能是因为是手势解锁是根视图。所以之后会改进。

GitHub地址:Swift实现手势解锁

关于爱程序网 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助