分类 iOS控件 下的文章

模仿网易彩票

注意点:
1.在新建项目时,注意项目的目录结构
2.具有共同操作的类可以新建一个父类来完成公共的操作
3.把实现代码放在控制器类的不同生命周期时调用的方法中,可以避免做重复的操作
4.图片只显示某一部分
5.webView的使用
6.UICollectionViewController的使用
7.模态框的使用
8.自定义TabBarItem

1.目录结构就不说了,mvc
2.共同的父类,子类只要继承自父类,并完成自身的数据赋值即可
//
//  JinBaseTableViewController.swift
//  lottery
//
//  Created by admin on 16/2/4.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
// 设置界面 UITableViewController 的父类,完成一些公共的操作
class JinBaseTableViewController: UITableViewController {
    // 存放设置选项模型数据
    var settings:[SettingGroup] = []
    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.backgroundColor = UIColor(patternImage: UIImage(imageLiteral: "bg"))
    }

    // 重写构造方法,算是填了下坑吧
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName : nibNameOrNil, bundle : nibBundleOrNil)
    }
    override init(style: UITableViewStyle) {
        super.init(style: style)
        // 在这里设置背景色的话 viewDidload 方法会被调用两次
//        self.tableView.backgroundColor = UIColor(patternImage: UIImage(imageLiteral: "bg"))
    }
    required convenience init?(coder aDecoder: NSCoder) {
        //        fatalError("init(coder:) has not been implemented")
        self.init(style: UITableViewStyle.Grouped)
        //return nil
    }
    convenience init()
    {
        self.init(style: UITableViewStyle.Grouped)
    }
    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 self.settings.count
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return self.settings[section].settings.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = JinTableViewCell.instance(tableView, setingData: self.settings[indexPath.section].settings[indexPath.row])
        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        self.settings[indexPath.section].settings[indexPath.row].block?()
    }
    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return self.settings[section].title
    }
    override func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
        return self.settings[section].footer
    }
}

子类代码

//
//  MyLotteryViewController.swift
//  lottery
//
//  Created by admin on 16/2/3.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class MyLotteryViewController: JinBaseTableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationItem.title = "设置"

        let group1 = SettingGroup()
        group1.settings.append(Setting(title: "推送和提醒", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow"), block: {
            [unowned self] in
            let controller = PushAndRemindController()
            controller.navigationItem.title = "推送和提醒"
            self.navigationController?.pushViewController(controller, animated: true)
        }))

        group1.settings.append(Setting(title: "摇一摇机选", titleImage: UIImage(imageLiteral: "handShake"), accessory: UISwitch()))
        group1.settings.append(Setting(title: "声音和效果", titleImage: UIImage(imageLiteral: "handShake"), accessory: UISwitch()))
        self.settings.append(group1)
        let group2 = SettingGroup()
        group2.settings.append(Setting(title: "检查版本更新", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow"), block: {
                [unowned self] in
                let hud = MBProgressHUD.showHUDAddedTo(self.tableView, animated: true)
                hud.label.text = "正在检查更新"
                let time = dispatch_time(DISPATCH_TIME_NOW, Int64(UInt64(2) * NSEC_PER_SEC))
                dispatch_after(time, dispatch_get_main_queue(), {
                    let image = UIImage(imageLiteral: "Checkmark").imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
                    let imageView = UIImageView(image: image)
                    hud.customView = imageView
                    hud.mode = MBProgressHUDMode.CustomView
                    hud.label.text = "已是最新版本"
                    hud.hideAnimated(true, afterDelay: 1)
                })
            }))
        group2.settings.append(Setting(title: "帮助", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow"), block: {
            [unowned self] in
            let controller = HelpViewController()
            // 因为是自定义的 UITabBarItem 所以这里设置了也无效
//            controller.hidesBottomBarWhenPushed = false
            controller.navigationItem.title = "帮助"

            self.navigationController?.pushViewController(controller, animated: true)
            }))
        group2.settings.append(Setting(title: "分享", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow")))
        group2.settings.append(Setting(title: "查看消息", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow")))
        group2.settings.append(Setting(title: "产品推荐", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow"), block: {
            [unowned self] in
            let controller = ProductViewController(collectionViewLayout : UICollectionViewFlowLayout())
            controller.navigationItem.title = "产品推荐"
            self.navigationController?.pushViewController(controller, animated: true)
            }))
        group2.settings.append(Setting(title: "投信", titleImage: UIImage(imageLiteral: "handShake"), accessoryImage: UIImage(imageLiteral: "CellArrow")))
        self.settings.append(group2)
    }

}
3.在控制器特定的生命周期做操作,可以避免重复的操作
//
//  JinNavigationController.swift
//  lottery
//
//  Created by admin on 16/2/3.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class JinNavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // 修改navgation标题栏的样式,在这里改也行,但是这个方法会执行多次,所以最好使用 initialize
//        self.navigationBar.setBackgroundImage(UIImage(imageLiteral: "NavBar64"), forBarMetrics: UIBarMetrics.Default)
//        self.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor(),NSFontAttributeName:UIFont.systemFontOfSize(20)]
        // Do any additional setup after loading the view.
    }
    override func preferredStatusBarStyle() -> UIStatusBarStyle {
        return UIStatusBarStyle.LightContent
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    // 当类第一次创建的时候调用这个方法,避免执行多次
    override class func initialize()
    {
        // 获取UINavigationBar对象
        weak var nav = UINavigationBar.appearance()
        // 设置背景图片
        nav!.setBackgroundImage(UIImage(imageLiteral: "NavBar64"), forBarMetrics: UIBarMetrics.Default)
        // 设置字体属性
        nav!.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor(),NSFontAttributeName:UIFont.systemFontOfSize(20)]
        // 设置返回按钮颜色
        nav!.tintColor = UIColor.whiteColor()
    }
}
4.图片显示某一部分
//
//  SquareViewController.swift
//  lottery
//
//  Created by admin on 16/2/4.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class SquareViewController: UIViewController {
    @IBOutlet weak var wheel: UIImageView!
    var link:CADisplayLink!
    var highlightedButton:UIButton!
    override func viewDidLoad() {
        // 转盘背景图片
        let imageView = UIImageView(image: UIImage(imageLiteral: "LuckyBackground"))
        imageView.frame = self.view.bounds
        self.view.insertSubview(imageView, atIndex: 0)
        // 获得屏幕scale,之后截取图片的时候会用到,不然图片截取之后是不规则的
        let scale = UIScreen.mainScreen().scale
        // 获得选项按钮背景图片
        let strology = UIImage(imageLiteral: "LuckyAstrology")
        let strologyPressed = UIImage(imageLiteral: "LuckyAstrologyPressed")
        // 获得截取图片的宽度
        let buttonW = strology.size.width / 12
        // 获得选项按钮的宽度
        let buttonFrame = CGRectMake(0, 0, buttonW, wheel.bounds.size.width * 0.5)
        // 设置图层的anchorPoint的值,旋转是围绕这个点旋转的
        let buttonLayerAnchorPoint = CGPointMake(0.5, 1)
        // 选项按钮放倒转盘中
        for var i = 0;i < 12;i++
        {
            let button = JinButton(type: UIButtonType.Custom)
            button.tag = i + 1
            button.frame = buttonFrame
            button.layer.anchorPoint = buttonLayerAnchorPoint
            button.center = CGPointMake(self.wheel.bounds.size.width * 0.5, self.wheel.bounds.size.width * 0.5)
            // 从大图片中截取一部分作为当前按钮的背景图片
            var buttonImage = CGImageCreateWithImageInRect(strology.CGImage, CGRectMake(buttonW * CGFloat(i) * scale, 0, buttonW * scale, strology.size.height * scale))
            button.setImage(UIImage(CGImage: buttonImage!), forState: UIControlState.Normal)
            buttonImage = CGImageCreateWithImageInRect(strologyPressed.CGImage, CGRectMake(buttonW * CGFloat(i) * scale, 0, buttonW * scale, strology.size.height * scale))
            // 设置选中状态下的图片
            button.setImage(UIImage(CGImage: buttonImage!), forState: UIControlState.Selected)
            button.setBackgroundImage(UIImage(imageLiteral: "LuckyRototeSelected"), forState: UIControlState.Selected)
            // 设置当前按钮的transform
            button.transform = CGAffineTransformMakeRotation(CGFloat(M_PI) / 6 * CGFloat(i))
            // 禁用高亮
            button.adjustsImageWhenHighlighted = false

            button.addTarget(self, action: "choiceNumber:", forControlEvents: UIControlEvents.TouchDown)
            self.wheel.addSubview(button)
        }
        // 添加开始选号按钮
        let choiceNumberButton = UIButton(type: UIButtonType.Custom)
        let choiceNumberButtonImage = UIImage(imageLiteral: "LuckyCenterButton")
        choiceNumberButton.bounds = CGRectMake(0, 0, choiceNumberButtonImage.size.width, choiceNumberButtonImage.size.height)
        choiceNumberButton.setBackgroundImage(choiceNumberButtonImage, forState: UIControlState.Normal)
        choiceNumberButton.setBackgroundImage(UIImage(imageLiteral: "LuckyCenterButtonPressed"), forState: UIControlState.Highlighted)
        choiceNumberButton.addTarget(self, action: "choiceNumberButtonClicked", forControlEvents: UIControlEvents.TouchDown)
        choiceNumberButton.center = self.wheel.center
        self.view.addSubview(choiceNumberButton)
        self.timer()
    }
    // 开始定时器
    func timer()
    {
        self.link = CADisplayLink(target: self, selector: "startRotation")
        self.link.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
    }
    // 旋转
    func startRotation()
    {
        self.wheel.transform = CGAffineTransformRotate(self.wheel.transform, CGFloat(M_PI) * 0.001)
    }
    // 选项按钮点击事件
    func choiceNumber(button:UIButton)
    {
        self.highlightedButton?.selected = false
        button.selected = true
        self.highlightedButton = button
    }
    func choiceNumberButtonClicked()
    {
        self.link?.invalidate()
        self.link = nil
        self.view.userInteractionEnabled = false
        UIView.transitionWithView(self.wheel, duration: 3, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
                [unowned self] in
                self.wheel.transform = CGAffineTransformRotate(self.wheel.transform, CGFloat(M_PI * 0.9))
            }, completion: {
                [unowned self] bool in
                let tag = Int(arc4random_uniform(12)) + 1
                let button:UIButton = self.wheel.viewWithTag(tag) as! UIButton
                self.choiceNumber(button)
                self.view.userInteractionEnabled = true
                //这里设置下延时执行,之前没用过的一种方式,这个参数有一些特别,而且没有提示。。。。记录下
                let minseconds = 3 * Double(NSEC_PER_SEC)
                let dtime = dispatch_time(DISPATCH_TIME_NOW, Int64(minseconds))
                if self.link == nil
                {
                    dispatch_after(dtime, dispatch_get_main_queue(), { [unowned self] () -> Void in
                        self.timer()
                    })
                }
        })
    }
}
5.webView的使用
//
//  HtmlViewController.swift
//  lottery
//
//  Created by admin on 16/2/4.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class HtmlViewController: UIViewController,UIWebViewDelegate {
    weak var help:Help!
    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = self.help.title
        let webview = UIWebView(frame: UIScreen.mainScreen().bounds)
        webview.delegate = self
        // 获得html文件路径
        let path = NSBundle.mainBundle().pathForResource("help.html", ofType: nil)
        // 获得请求字串
        let request = NSURLRequest(URL: NSURL(fileURLWithPath: path!))
        // 使用webView加载html
        webview.loadRequest(request)
        // 因为是使用模态框加载的这个控制器,所以需要手动设置下返回按钮
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "返回", style: UIBarButtonItemStyle.Plain, target: self, action: "back")
        // 把webView添加进视图
        self.view.addSubview(webview)
    }
    // 返回之前的控制器
    func back()
    {
        self.dismissViewControllerAnimated(true, completion: nil)
    }
    // webView代理方法,加载完成时调用
    func webViewDidFinishLoad(webView: UIWebView) {
        // 执行js代码
        let jsCode = "window.location.href='#\(self.help.id)'"
        webView.stringByEvaluatingJavaScriptFromString(jsCode)
    }
}
6.UICollectionViewController的使用
//
//  ProductViewController.swift
//  lottery
//
//  Created by admin on 16/2/4.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
let collectionIdentifier = "jinCollectionCell"
class ProductViewController: UICollectionViewController {
    // 产品数据模型数组
    lazy var products:[Product] = Product.instanceOfFile()
    // 重写构造方法
    override init(collectionViewLayout layout: UICollectionViewLayout) {
        // cell的大小是通过Layout来控制
        let layout = UICollectionViewFlowLayout()
        layout.itemSize = CGSizeMake(100, 120)
        super.init(collectionViewLayout : layout)
    }
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName : nibNameOrNil, bundle : nibBundleOrNil)
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        self.collectionView?.backgroundColor = UIColor.whiteColor()
        // 和tableView不同的是,需要先注册cell
//        self.collectionView?.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: collectionIdentifier)
        self.collectionView?.registerNib(UINib(nibName: "JinCollectionCell", bundle: NSBundle.mainBundle()), forCellWithReuseIdentifier: collectionIdentifier)
    }
    // 返回分组数
    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }
    // 返回分组数据条数
    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.products.count
    }
    // 返回cell
    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        // 从缓冲池中获取cell
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(collectionIdentifier, forIndexPath: indexPath) as! JinCollectionCell
        cell.product = self.products[indexPath.row]
        return cell
    }
    override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        let appliction = UIApplication.sharedApplication()
        // 打开url
        appliction.openURL(NSURL(string: self.products[indexPath.row].url)!)
    }
}
7.模态框的使用
//
//  HelpViewController.swift
//  lottery
//
//  Created by admin on 16/2/4.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class HelpViewController: JinBaseTableViewController {
    var helps:[Help] = Help.instanceOfFile()
    override func viewDidLoad() {
        super.viewDidLoad()
        print(helps)
        let group1 = SettingGroup()
        helps.forEach({
            val in
            group1.settings.append(Setting(title: val.title!, accessoryImage: UIImage(imageLiteral: "CellArrow")))
        })

        self.settings.append(group1)
    }
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        // 创建要显示的控制器
        let html = HtmlViewController()
        html.help = self.helps[indexPath.row]
        // 创建导航控制器并把要显示的控制器作为根控制器
        let nav = UINavigationController(rootViewController: html)
        // 显示模态窗口
        self.presentViewController(nav, animated: true, completion: nil)
    }
}
8.自定义TabBarItem
//
//  JinTabBarItem.swift
//  lottery
//
//  Created by admin on 16/2/3.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
// 自定义协议
@objc protocol JinTabBarItemDelegate
{
    optional func tabBarButtonClicked(index:Int)
}
// 自定义 tabbaritem 类
class JinTabBarItem: UIView {

    // 记录当前选中状态的按钮
    weak var selectedTabBarButton:UIButton!
    // 当前对象代理
    weak var tabBarButtonDelegate:JinTabBarItemDelegate!
    // 添加item按钮
    func addTabBarButton(normalImage:String,selectedImage:String)
    {
        let tabBarButton = UIButton(type: UIButtonType.Custom)
        // 设置图片
        tabBarButton.setBackgroundImage(UIImage(imageLiteral: normalImage), forState: UIControlState.Normal)
        tabBarButton.setBackgroundImage(UIImage(imageLiteral: selectedImage), forState: UIControlState.Selected)
        // 设置图片方法
        tabBarButton.addTarget(self, action: "changeTabBarButtonStatus:", forControlEvents: UIControlEvents.TouchDown)
        // button 没有 setHighlighted 方法啊  我去
        tabBarButton.adjustsImageWhenHighlighted = false
        self.addSubview(tabBarButton)
    }
    // 按钮被点击时的响应事件
    func changeTabBarButtonStatus(button:UIButton)
    {
        // 修改当前选中按钮状态
        self.selectedTabBarButton?.selected = false
        // 修改当前点击按钮状态
        button.selected = true
        // 修改当前被选中的按钮
        self.selectedTabBarButton = button
        // 执行代理方法
        self.tabBarButtonDelegate?.tabBarButtonClicked?(self.subviews.indexOf(button)!)
    }
    // 完成按钮的布局
    override func layoutSubviews() {
        // 获得当前的子按钮数量
        let buttonCount = self.subviews.count
        // 获得当前状态下按钮的宽度
        let buttonWidth = self.frame.size.width / CGFloat(buttonCount)
        for(var i = 0;i < buttonCount;i++)
        {
            let tabBarButton = self.subviews[i] as! UIButton
            // 默认第一个按钮为选中
            if i == 0
            {
                self.changeTabBarButtonStatus(tabBarButton)
            }
            // 设置按钮fram
            tabBarButton.frame = CGRectMake(CGFloat(i) * buttonWidth, 0, buttonWidth, self.frame.size.height)
        }
    }
}

代码网址:https://git.oschina.net/JinDev/lottory.git

模态窗口的使用

连线的话,拖动之后选择 Pressent Modally就可以了
代码

跳转
let storyboard = UIStoryboard(name: "Main", bundle: nil)
var modal = storyboard.instantiateViewControllerWithIdentifier("Modal")
self.presentViewController(modal, animated: true, completion: nil)
从模态窗中返回
self.dismissViewControllerAnimated(true, completion: nil)

在模态窗中没有 Navigation Item ,手动添加也没用

UITabBarController的使用

//
//  AppDelegate.swift
//  TabbarWithCode
//
//  Created by admin on 16/1/22.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        let window = UIWindow(frame:UIScreen.mainScreen().bounds)
        let tabbar = UITabBarController() // 初始化tabbar控制器
        window.rootViewController = tabbar // 设置window根控制器
        window.makeKeyAndVisible()
        self.window = window

        let c1 = UIViewController()
        c1.view.backgroundColor = UIColor.grayColor()
        c1.tabBarItem.title = "通讯录" // tabbarbutton的标题
        c1.tabBarItem.image = UIImage(imageLiteral: "tab_buddy_nor") // tabbarbutton的图片
        c1.tabBarItem.badgeValue = "10" // tabbarbutton显示的数字
//        tabbar.addChildViewController(c1) // 逐条添加
        let c2 = UIViewController()
        c2.view.backgroundColor = UIColor.blueColor()
        c2.tabBarItem.title = "设置"
        c2.tabBarItem.image = UIImage(imageLiteral: "tab_me_nor")
        c2.tabBarItem.badgeValue = "2"
//        tabbar.addChildViewController(c2)
        let c3 = UIViewController()
        c3.view.backgroundColor = UIColor.blackColor()
        c3.tabBarItem.title = "动态"
        c3.tabBarItem.image = UIImage(imageLiteral: "tab_qworld_nor")
        c3.tabBarItem.badgeValue = "8"
//        tabbar.addChildViewController(c3)
        let c4 = UIViewController()
        c4.view.backgroundColor = UIColor.whiteColor()
        c4.tabBarItem.title = "消息"
        c4.tabBarItem.image = UIImage(imageLiteral: "tab_recent_nor")
        c4.tabBarItem.badgeValue = "99"
//        tabbar.addChildViewController(c4)
        tabbar.viewControllers = [c1,c2,c3,c4]// 一次性添加
        return true
    }

    func applicationWillResignActive(application: UIApplication) {

    }

    func applicationDidEnterBackground(application: UIApplication) {
            }

    func applicationWillEnterForeground(application: UIApplication) {

    }

    func applicationDidBecomeActive(application: UIApplication) {

    }

    func applicationWillTerminate(application: UIApplication) {

    }
}

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)
}

代码创建UINavigationController

首先,需要在项目设置去掉 Main Interface

在代码中自定义UIWindow对象,并设置控制器,注意,我这里用到的控制器都在关联了xib的
//
//  AppDelegate.swift
//  代码创建导航
//
//  Created by zhang on 16/1/16.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.

        // 先取消项目设置中的 Main Interface
        // 初始化窗口对象
        let window = UIWindow()

        // 初始化 navigation 对象
        // 初始化默认显示的控制器
        let mainController = UIViewControllerA()

        // 初始化 navigation
        // 这种方式设置初始化需要后面设置下默认控制器
//        let navigation = UINavigationController()
        // 在初始化的时候指定默认控制器
        let navigation = UINavigationController(rootViewController: mainController)

        // 下面的是两种设置 navigation 默认控制器的方法
//        navigation.addChildViewController(mainController)
//        navigation.pushViewController(mainController, animated: true)

        // 设置当前窗口的根控制器
        window.rootViewController = navigation

        self.window = window
        // 当前窗口作为主窗口并显示
        self.window?.makeKeyAndVisible()
        return true
    }
}
navigation的根控制器
//
//  UIViewControllerA.swift
//  代码创建导航
//
//  Created by zhang on 16/1/16.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class UIViewControllerA: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // 设置导航栏标题
        self.title = "第一个控制器"

        // 导航条左边的按钮
        let addButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Add, target: nil, action: nil)
        let cameraButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Camera, target: nil, action: nil)
        // 赋值
        self.navigationItem.leftBarButtonItems = [addButton,cameraButton]

        // 设置导航栏右边的按钮
        let composeButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Compose, target: nil, action: nil)
        let actionButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Action, target: nil, action: nil)
        self.navigationItem.rightBarButtonItems = [composeButton,actionButton]


        // 设置返回
        let backButton = UIBarButtonItem(title: "返回", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)

        self.navigationItem.backBarButtonItem = backButton
        // Do any additional setup after loading the view.
    }

    @IBAction func nextController(sender: UIButton) {
//        let controller = UIViewControllerB(nibName: "UIViewControllerB", bundle : nil)
        let controller = UIViewControllerB()
        // 把下个控制器对象加入 navigation 的栈,因为navigavtion会显示栈顶的控制器,所以,相当于跳转到下个控制器
        self.navigationController?.pushViewController(controller, animated: true)
    }
}
第二个控制器
//
//  UIViewControllerB.swift
//  代码创建导航
//
//  Created by zhang on 16/1/16.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class UIViewControllerB: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.title = "第二个控制器"

        // Do any additional setup after loading the view.
    }
    // 返回
    @IBAction func back(sender: AnyObject) {
        // 移除当前控制器,回到上一个,相当于返回
        self.navigationController?.popViewControllerAnimated(true)
    }
    // 跳转到下个controller
    @IBAction func next(sender: AnyObject) {
        let controller = UIViewControllerC()
        self.navigationController?.pushViewController(controller, animated: true)
    }
}
第三个控制器
//
//  UIViewControllerC.swift
//  代码创建导航
//
//  Created by zhang on 16/1/16.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class UIViewControllerC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "第三个控制器"
        // 这只 item titleview
        self.navigationItem.titleView = UIImageView(image: UIImage(imageLiteral: "1"))
        // Do any additional setup after loading the view.
    }
    @IBAction func back(sender: AnyObject) {
        // 回到上一个控制器
        self.navigationController?.popViewControllerAnimated(true)
    }

    @IBAction func backRoot(sender: AnyObject) {
        // 回到根控制器
        self.navigationController?.popToRootViewControllerAnimated(true)
    }
}