swift版本通讯录

注意点:控制器之间的跳转(navigation),数据本地存储,控制器之前传递数据

首先是数据模型,主要注意遵循了NSCoding协议和实现了协议的方法,这样对象才能存储
//
//  Adress.swift
//  AdressBook
//
//  Created by admin on 16/1/21.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
// 遵循了NSCoding协议
class Address: NSObject,NSCoding {
    var name:NSString!
    var address:NSString!
    // 构造方法
    init(name:NSString,address:NSString) {
        self.name = name
        self.address = address
    }
    // NSCoding协议构造方法
    required init?(coder aDecoder: NSCoder) {
        self.name = aDecoder.decodeObjectForKey("name") as! NSString
        self.address = aDecoder.decodeObjectForKey("address")  as! NSString
    }
    // NSCoding协议解码方法
    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(self.name, forKey: "name")
        aCoder.encodeObject(self.name, forKey: "address")
    }
    // 写文件类方法,其实开始我是打算用 NSMutableData的方法来存储的,用NSMutableData的话,在读取的时候会有点麻烦
    class func writeAddresses(addresses:[Address])
    {
        NSKeyedArchiver.archiveRootObject(addresses, toFile: addressesPath)
    }
    // 对文件类方法
    class func readeAddresses()->[Address]
    {
        let mutableData = NSKeyedUnarchiver.unarchiveObjectWithFile(addressesPath)
        if mutableData == nil
        {
            return []
        }
        else
        {
            return mutableData as! [Address]
        }

    }
}
两个路径配置
import Foundation
// 用户信息存放路径
let userInfoPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).last! + "/userInfo.plist"
let addressesPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).last! + "/addresses.plist"
登录控制器
//
//  LoginController.swift
//  AddressBook
//
//  Created by admin on 16/1/20.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class LoginController: UIViewController {
    @IBOutlet weak var userName: UITextField!
    @IBOutlet weak var password: UITextField!
    @IBOutlet weak var loginButton: UIButton!
    @IBOutlet weak var rememberPassword: UISwitch!
    @IBOutlet weak var autoLogin: UISwitch!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    // 文本框改变的时候修改登录按钮的可见性
    @IBAction func checkUserInfo() {
        if(userName.text! == "" || password.text! == "")
        {
            loginButton.enabled = false
        }
        else
        {
            loginButton.enabled = true
        }
    }
    // 登录
    @IBAction func loginAction(sender: AnyObject) {
        let progress = MBProgressHUD(view: self.view)
        self.view.addSubview(progress)
        progress.dimBackground = true
        progress.labelText = "正在登录...."
        progress.show(true)
        self.view.endEditing(true)

        //这里设置下延时执行,之前没用过的一种方式,这个参数有一些特别,而且没有提示。。。。记录下
        let minseconds = 1 * Double(NSEC_PER_SEC)
        let dtime = dispatch_time(DISPATCH_TIME_NOW, Int64(minseconds))
        dispatch_after(dtime, dispatch_get_main_queue(), { () -> Void in
            progress.hide(true)
            if(self.userName.text! == "jin" && self.password.text! == "jin")
            {

                // 进入下个控制器,以segue的方式跳转
                self.performSegueWithIdentifier("AddressBook", sender: nil)
                let userDefault = NSUserDefaults.standardUserDefaults()
                // 记录用户偏好
                userDefault.setBool(self.rememberPassword.on, forKey: "rememberPassword")
                userDefault.setBool(self.autoLogin.on, forKey: "autoLogin")
                userDefault.synchronize()
                // 如果选择了记住密码就记住密码
                if self.rememberPassword.on
                {
                    self.savePasssword()
                }

            }
            else
            {
                let hud = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
                hud.mode = MBProgressHUDMode.Text
                hud.labelText = "登录失败,请重试。。。"
                hud.hide(true, afterDelay: 2)
            }
        })
    }
    // 保存密码到文件
    func savePasssword()
    {
        // 这里保存的方式是直接使用的数据类型自带的写文件方法
        let userInfo = NSMutableDictionary()
        userInfo.setValue(self.userName.text, forKey: "userName")
        userInfo.setValue(self.password.text, forKey: "password")
        userInfo.writeToFile(userInfoPath, atomically: true)
    }
    // 自动登录时勾选记住密码
    @IBAction func autolLoginAction(sender: AnyObject) {
        self.rememberPassword.setOn(self.autoLogin.on ? self.autoLogin.on : self.rememberPassword.on, animated: true)
    }
    @IBAction func rememberChange(sender: AnyObject) {
        self.autoLogin.setOn(self.rememberPassword.on ? self.autoLogin.on : self.rememberPassword.on, animated: true)
    }
    override func viewWillAppear(animated: Bool) {
        // 从文件中读取保存的用户信息
        let userInfo = NSDictionary(contentsOfFile: userInfoPath)
        // 给控件赋值
        self.userName.text = (userInfo?["userName"] != nil) ? (userInfo?["userName"] as! String) : ""
        self.password.text = (userInfo?["password"] != nil) ? (userInfo?["password"] as! String) : ""
        // 检查用户框的信息,用以开启登录按钮可用性
        checkUserInfo()
        // 获得用户偏好设置,
        let userDefault = NSUserDefaults.standardUserDefaults()
        // 设置偏好设置按钮的状态
        self.rememberPassword.on = userDefault.boolForKey("rememberPassword")
        self.autoLogin.on = userDefault.boolForKey("autoLogin")
        // 检查状态,符合则自动登录
        if self.autoLogin.on && loginButton.enabled
        {
            self.loginAction(self)
        }
    }
    // 转向下个控制器的时候会调用这个方法,
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        super.prepareForSegue(segue, sender: sender)
        // 源控制器
//        print(segue.sourceViewController)
        // 目标控制器
//        print(segue.destinationViewController)
        if(segue.destinationViewController is AddressBookController)
        {
            // 设置控制器的标题
            segue.destinationViewController.title = self.userName.text
            segue.destinationViewController.navigationItem.title = self.userName.text
        }
    }
}
联系人列表
//
//  AddressBookController.swift
//  AddressBook
//
//  Created by admin on 16/1/20.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
// 遵循了两个自定的代理协议
class AddressBookController: UITableViewController,AddAddressControllerDelegate,EditAddressControllerDelegate {
    @IBOutlet weak var titleView: UINavigationItem!
    // 联系人数据数组
    var addreses:[Address]! = Address.readeAddresses()
        {
            didSet
            {
                Address.writeAddresses(addreses)
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    // 登出
    @IBAction func logout(sender: UIBarButtonItem) {
        let userInfo = NSDictionary(contentsOfFile: userInfoPath)
//        userInfo.setValue("", forKey: "userName")
        userInfo!.setValue("", forKey: "password")
        userInfo!.writeToFile(userInfoPath, atomically: true)
        self.navigationController?.popToRootViewControllerAnimated(true)
    }
    // 删除按钮点击之后,改变编辑状态
    @IBAction func deleteAddress(sender: UIBarButtonItem) {
        self.tableView.editing = !self.tableView.editing
    }
    // 根据编辑状态做相应操作
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        switch editingStyle
        {
        case UITableViewCellEditingStyle.Delete :
            self.addreses.removeAtIndex(indexPath.row)
            self.tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: indexPath.row, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Fade)
            break
        default :
            break
        }
    }
    // 跳转时判断,不同的控制器做不同的操作
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        super.prepareForSegue(segue, sender: nil)
        if segue.destinationViewController is LoginController// 返回登录控制器直接返回
        {
            segue.destinationViewController.viewDidLoad()
        }
        else if segue.destinationViewController is AddAddressController// 添加控制器则设置代理
        {
            (segue.destinationViewController as! AddAddressController).addAddressDelegate = self
        }
        else if segue.destinationViewController is EditAddressController// 编辑控制器则设置代理以及传递当前选择的address模型
        {
            let dest = segue.destinationViewController as! EditAddressController
            dest.address = self.addreses[(tableView.indexPathForSelectedRow?.row)!]
            dest.editAddressDelegate = self
        }
    }
    // 执行保存数据代理方法
    func saveAddressButtonClicked(address: Address) {
        self.addreses.append(address)
        // 插入新行数据
        self.tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: self.addreses.count - 1, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Fade)
    }
    // 编辑address代理方法,用以刷新数据之后改变cell为最新内容
    func ediitAddressSaveButonClicked(address:Address) {
        let index = self.addreses.indexOf(address)// 找到当前改变的addree的下标
        self.addreses[index!] = address // 覆盖值
        self.tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: index!, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Fade) // 刷新cell
//        print(index)
    }
    // MARK: - Table view data source
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.addreses.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let identifer = "addressCell"
        // 从缓冲池中获取cell
        var cell:UITableViewCell! = tableView.dequeueReusableCellWithIdentifier(identifer)
        // 当没有获取到cell的时候,实例化新的cell
        cell = (cell == nil) ? UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: identifer) : cell
        cell.textLabel?.text = self.addreses[indexPath.row].name as String
        cell.detailTextLabel?.text = self.addreses[indexPath.row].address as String
        return cell
    }
    // 点击cell执行方法
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        self.performSegueWithIdentifier("EditAddress", sender: nil)
    }
    // 设置cell编辑状态的style
    override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
        return UITableViewCellEditingStyle.Delete
    }
}
添加联系人
//
//  AddAdressController.swift
//  AdressBook
//
//  Created by admin on 16/1/21.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class AddAddressController: UIViewController {

    @IBOutlet weak var saveAddressButton: UIBarButtonItem!
    @IBOutlet weak var name: UITextField!
    @IBOutlet weak var address: UITextField!
    weak var addAddressDelegate:AddAddressControllerDelegate!
    // 检测信息是否出入完全
    @IBAction func checkAddressInfo(sender: AnyObject) {
        self.saveAddressButton.enabled = self.name.text != "" && self.address.text != ""
    }
    // 保存数据按钮
    @IBAction func saveAddress(sender: AnyObject) {
        let address = Address(name: self.name.text!, address: self.address.text!)
        self.addAddressDelegate?.saveAddressButtonClicked?(address)
        self.navigationController?.popViewControllerAnimated(true)
    }
}
// 保存数据代理协议
@objc protocol AddAddressControllerDelegate
{
    optional func saveAddressButtonClicked(address:Address)
}
编辑联系人
//
//  EditAddressController.swift
//  AdressBook
//
//  Created by admin on 16/1/22.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
class EditAddressController: UIViewController,UIAlertViewDelegate {
    @IBOutlet weak var nameTextfield: UITextField!
    @IBOutlet weak var addressTextfield: UITextField!
    @IBOutlet weak var down: UIBarButtonItem!
    weak var address:Address! // 当前修改的模型
    weak var editAddressDelegate:EditAddressControllerDelegate!// 代理
    override func viewDidLoad() {
        self.nameTextfield.text = address.name as String
        self.addressTextfield.text = address.address as String
    }
    // 保存修改之后的数据
    @IBAction func saveAddress(sender: UIBarButtonItem) {
        // 更改模型数据
        self.address.name = self.nameTextfield.text! as String
        self.address.address = self.addressTextfield.text! as String
        // 执行代理方法
        self.editAddressDelegate?.ediitAddressSaveButonClicked?(self.address)
        // 返回控制器
        self.navigationController?.popViewControllerAnimated(true)
    }
    // 判断用户修改改变确认按钮可用性
    @IBAction func checkAddress(sender: UITextField) {
        if nameTextfield.text != "" && addressTextfield.text != "" && nameTextfield.text != self.address.name && addressTextfield.text != self.address.address
        {
            down.enabled = true
        }
        else
        {
            down.enabled = false
        }
    }
    // 退出按钮事件
    @IBAction func cancel(sender: UIBarButtonItem) {
        if self.down.enabled
        {
            // 使用 UIAlertView 会有警告,所以改用 UIAlertController 了

//            let alert = UIAlertView(title: "确认放弃修改么?", message: "确认放弃修改么?", delegate: self, cancelButtonTitle: "继续修改", otherButtonTitles:"放弃修改")
//            alert.delegate = self
//            alert.show()
            // 使用 UIAlertController
            let alert = UIAlertController(title: "确认放弃修改么?", message: "确认放弃修改么?", preferredStyle: UIAlertControllerStyle.Alert)
            // 添加按钮
            alert.addAction(UIAlertAction(title: "放弃修改", style: UIAlertActionStyle.Destructive, handler: {
                alert in
                self.navigationController?.popViewControllerAnimated(true)
            }))
            // 添加按钮
            alert.addAction(UIAlertAction(title: "继续修改", style: UIAlertActionStyle.Destructive, handler: nil))
            // 显示
            self.view.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
        }
        else
        {
            self.navigationController?.popViewControllerAnimated(true)
        }

    }
    // UIAlertView 代理方法
    func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) {
        if buttonIndex == 1
        {
            self.navigationController?.popViewControllerAnimated(true)
        }
    }
}
// 修改address代理协议
@objc protocol EditAddressControllerDelegate
{
    optional func ediitAddressSaveButonClicked(address:Address)
}

标签: swift, ios控件

添加新评论