Swift 编写的一个 ToDo App

以下所有代码都是使用Xcode Version 6.0.1 (6A317)编写的。

由于团队开发的时候使用stroyboard在合并的时候有诸多不便,所有还是使用.xib文件编写这个ToDo App.

想要实现的功能是:TableView 上可以增加待做选项,并按照时间先后排序,可以实现删除,到点通知功能。

想要实现的效果如下:

      

步骤:

1、新建一个基于Singal View Application 的工程,然后删掉storyboard,在新建两个新文件 Main.xib 和 Main.swift 作为主要的ViewController,打开 Main.xib 将 File‘s Owner的l类属性改为 Main(这样才可以将关联变量拖动到 Mian.swift )。

Main.xib 页面UI,一个用于展示todo list 的 tableView,然后关联一个 tableView 变量到 Main.swift文件

2、接下来设置 Mian 为rootViewController,在AppDelegate.swift中做写如下代码:

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

        var viewController = Main(nibName: "Main", bundle: nil)
        navigationController = UINavigationController(rootViewController: viewController)

        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window?.rootViewController = navigationController
        self.window?.makeKeyAndVisible()

        return true
    }

注意: var viewController =
Main(nibName:"Main", bundle: nil) ,用来将 Mian.xib 与 Mian.swift 进行绑定。run 一下你就可以看到界面了。

3、然后在Main.swift 中编写一下TableView 的数据源和代理的方法。这里我们用的是 自定义的 Cell。所有新建一个 Cell.xib 和 Cell.swift 并将它们关联起来,做法和上面的相同,Cell.xib UI 如下。

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 20
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? Cell
        var str: String
        if (cell == nil) {
            let nibs:NSArray = NSBundle.mainBundle().loadNibNamed("Cell", owner: self, options: nil)
            cell = nibs.lastObject as? Cell
        }

        cell?.todoTitle.text = "toDoTitle"
        cell?.time.text = "\(NSDate())"
        cell?.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
        return cell!
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    }

    func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == UITableViewCellEditingStyle.Delete {

        }
    }

run 一下就可以看到如下效果:

注意:考虑到UITableView的滚动性能,Cell 的重用非常重要,通过上面的 println(cell),滚动Cell,观察打印出来的 Cell 地址,可以看到 Cell 并没有进行重用。在

override func viewDidLoad() { } 中添加下面的代码使 Cell 重用。

var bundle: NSBundle = NSBundle.mainBundle()
        var nib: UINib = UINib(nibName: "Cell", bundle: bundle)
        tableView.registerNib(nib, forCellReuseIdentifier: cellIdentifier)

4、以上讲到的都是些静态的数据,接下来我们做一些动态数据。

4.1、在NavigationBar 增加一个 ‘+’ 按钮,用来给用户增加待做选项

self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Add, target: self, action: "addItem")

响应函数:

func addItem() {
        let addVC: Add = Add(nibName: "Add", bundle: nil)
        addVC.delegate = self;
        self.presentViewController(addVC, animated: true, completion: nil)
    }

4.2、新增一个 Add.xib 和 Add.swift 让用户输入待做选项,记得绑定(同步骤1),Add.xib UI如下:

为了在Main.swift 中接收到 Add.xib 中用户输入的信息,我们在 Add.swift 定义一个协议,然后Main.swift 遵循这个协议,在Add.xib 界面消失前获取用户输入信息。

protocol AddProtocal {
    func didCompleted(addObject: Add)
}

Add.swift 代码如下:

//
//  Add.swift
//  ToDoApp
//
//  Created by aaron on 14-9-17.
//  Copyright (c) 2014年 The Technology Studio. All rights reserved.
//

import UIKit

protocol AddProtocal {
    func didCompleted(addObject: Add)
}

class Add: UIViewController {

    @IBOutlet var todo: UITextField!
    @IBOutlet var desc: KCTextView!
    @IBOutlet var time: UIDatePicker!
    @IBOutlet var completeBtn: UIButton!
    var delegate: AddProtocal?

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    override func viewWillAppear(animated: Bool) {
        setup()
    }

    func setup() {
        completeBtn.layer.cornerRadius = 5.0
        todo.placeholder = "请输入待做项"
//        desc.placeholder = "请输入详细描述。"
        todo.text = self.todo.text
        desc.text = self.desc.text
        time.date = self.time.date
        time.minimumDate = NSDate.date()

        if delegate? == nil {
            todo.textColor = UIColor.lightGrayColor()
            todo.userInteractionEnabled = false
            desc.textColor = UIColor.lightGrayColor()
            desc.userInteractionEnabled = false
            time.userInteractionEnabled = false
            completeBtn.setTitle("好", forState: UIControlState.Normal)
        }else {
            todo.textColor = UIColor.blackColor()
            todo.userInteractionEnabled = true
            desc.textColor = UIColor.blackColor()
            desc.userInteractionEnabled = true
            time.userInteractionEnabled = true
            completeBtn.setTitle("完成", forState: UIControlState.Normal)
        }

        let swipeGesture = UISwipeGestureRecognizer(target: self, action:"hideKeyboard")
        swipeGesture.direction = UISwipeGestureRecognizerDirection.Down
        swipeGesture.numberOfTouchesRequired = 1
        self.view.addGestureRecognizer(swipeGesture)

    }

    func hideKeyboard() {
        println("swipeGesture....")
        todo.resignFirstResponder()
        desc.resignFirstResponder()
    }

    func shakeAnimation(sender: AnyObject) {
        let animation = CAKeyframeAnimation()
        animation.keyPath = "position.x"
        animation.values = [0, 10, -10, 10, 0]
        animation.keyTimes = [0, 1/6.0, 3/6.0, 5/6.0, 1]
        animation.duration = 0.4
        animation.additive = true
        sender.layer.addAnimation(animation, forKey: "shake")
    }

    @IBAction func completeTouch(sender: AnyObject) {
        if (countElements(todo.text) > 0){
            delegate?.didCompleted(self)
            self.dismissViewControllerAnimated(true, completion: nil)
        }else{
            shakeAnimation(todo)
        }
    }
    @IBAction func editingDidEnd(sender: UITextField) {
        if (countElements(sender.text) == 0) {
           shakeAnimation(todo)
        }

    }

}

ToDo项为空时会有一个小小的提示动画:

Add.swift 中的关联变量 desc 是UITextView 类型的,UITextView 不像 UITextField 有 placeHolder ,所以这里我们引入一个 OC 写的 KCTextView ,由 KCTextView 代替 UITextView,swift 中引用 OC 写的 API 容易,新建一个 .h ,把你需要用到的头文件统统写在里面,然后 Build Settings 中的 Object-C Bridging Header 写入 .h 文件的路径即可,接着就可以正常使用
OC 写的接口了。

Main.swift 实现 AddProtocal,并实现协议规定的函数:

func didCompleted(addObject: Add) {

        toDoData.append(addObject)
        tableView.reloadData()
}

toDoData的是一个 Add类型的可变数组。

Main.swift 代码如下:

//
//  Main.swift
//  ToDoApp
//
//  Created by aaron on 14-9-16.
//  Copyright (c) 2014年 The Technology Studio. All rights reserved.
//

import UIKit

class Main: UIViewController, UITableViewDataSource, UITableViewDelegate, AddProtocal {

    @IBOutlet var tableView: UITableView!
    let cellIdentifier = "Cell"

    var toDoData = [Add]()

    override func viewDidLoad() {
        super.viewDidLoad()
        setup()
        registerCell()
    }

    func setup() {
        self.title = "To Do List"
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Add, target: self, action: "addItem")

    }

    func registerCell() {
        var bundle: NSBundle = NSBundle.mainBundle()
        var nib: UINib = UINib(nibName: "Cell", bundle: bundle)
        tableView.registerNib(nib, forCellReuseIdentifier: cellIdentifier)
    }

    func addItem() {
        let addVC: Add = Add(nibName: "Add", bundle: nil)
        addVC.delegate = self;
        self.presentViewController(addVC, animated: true, completion: nil)
    }

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

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? Cell
        var str: String
        if (cell == nil) {
            let nibs:NSArray = NSBundle.mainBundle().loadNibNamed("Cell", owner: self, options: nil)
            cell = nibs.lastObject as? Cell
        }

        let addObject = toDoData[indexPath.row] as Add
        cell?.todoTitle.text = addObject.todo.text
        cell?.time.text = dateFormatter(addObject.time.date)
        cell?.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
        return cell!
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let addVC = toDoData[indexPath.row] as Add
        addVC.delegate = nil
        self.presentViewController(addVC, animated: true, completion: nil)
    }

    func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == UITableViewCellEditingStyle.Delete {
            toDoData.removeAtIndex(indexPath.row)
            tableView.reloadData()
        }
    }

    func didCompleted(addObject: Add) {

        toDoData.append(addObject)
        toDoData.sort({ self.dateFormatter($0.time.date) < self.dateFormatter($1.time.date)})//按时间排序
        tableView.reloadData()

    }

    func dateFormatter(date: NSDate) -> String {
        let formatter = NSDateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        formatter.locale = NSLocale(localeIdentifier: NSGregorianCalendar)
        let dateStr = formatter.stringFromDate(date)
        return dateStr
    }

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

}

最后你大概可以看到这样的效果:

5、最后一步,为待做项目添加通知功能,这一功能在之前的文章(ios8 notifacation in swift)中就讲过了,这里就不重复写了。完整的项目代码我发在github上来,需要的到这里拿。

时间: 2024-10-20 19:24:58

Swift 编写的一个 ToDo App的相关文章

2、编写第一个django app

1.创建project django-admin startproject mysite 输入以上命令后, 在当前目录下生成 mysite 目录 和 相应文件: [[email protected] django]# tree . . └── mysite 项目容器, django 不关注, 可随意命名 ├── manage.py 一种命令行工具,允许你以多种方式与该 Django 项目进行交互,可用 python manage.py help 查看使用方式 └── mysite 项目的pyth

0.从零安装配置Android Studio并编写第一个Android App

0. 所需的安装文件 笔者做了几年WP,近来对Android有点兴趣,尝试一下Android开发,废话不多说,直接进入主题,先安装开发环境,笔者的系统环境为windows8.1&x64. 安装Android Studio需要如下准备2个文件: Android Studio:下载地址(https://dl.google.com/dl/android/studio/install/1.2.2.0/android-studio-bundle-141.1980579-windows.exe) jdk7:

[转]IFTTT开源Swift编写的帧动画框架--RazzleDazzle

RazzleDazzle 是IFTTT开源的一个iOS帧动画框架,用Swift编写,非常适用于APP初次使用时的介绍和引导信息.RazzleDazzle由IFTTT此前开源的一款Objective-C滚动帧动画库JazzHands发展而来.JazzHands是UIKit一个简单的关键帧基础动画框架,可通过手势.scrollview.KVO或者ReactiveCocoa控制动画,被IFTTT应用在IFTTT for iPhone上.多款知名应用程序都使用了JazzHands这个框架,目前其在git

[iOS] 用 Swift 开发一个 TODO 应用

原文地址:http://blog.callmewhy.com/2014/09/15/todo-list-in-swift/ 背景 相信不少 iOS 程序员对于 Swift 依旧持以观望的态度,一来是这小家伙刚出来没几天,本身还处于完善的阶段:二来是学习的成本较高,看完官方文档怎么也要个几天的时间:三来是反正最近几年很难在工程项目里推广使用,工作又用不到,那我学个锤子呐. 是的,我一开始也是这么想的.直到有一天,我遇到了它:Swift Tutorial - To Do List App.这是 Yo

Swift编写的一些完整的app

收集了一些实用swift编写的app,这些demo都是不错的值得学习的. 知乎日报  Swift-ZhihuDaily Swift版知乎日报 参照了YANGReal的糗事百科和uitableview的例子,这些虽说是demo,也是完整的app,使用了爱加密的app加密技术,非常不错,感谢! 我觉得学习一门语言光看是没用的,只有投入到实践项目中去,才能最快速的掌握它,有兴趣的同学可以和我一起来把这个项目完善,目前只做了列表页和内容页两个页面. 源码地址:Swift-ZhihuDaily 新浪新闻客

PhoneGap 教程:一个跨平台的 Todo App

PhoneGap 是一个允许开发者使用熟悉的网页开发技术,例如HTML,CSS 和 JavaScript 去开发跨平台应用的手机开发框架. 也就是说你可以使用 PhoneGap 架构开发一款应用,不需要重写额外一行代码就可以将它部署到多个移动应用平台. 在这个教程中,你将学习使用 PhoneGap 去创建一款简单的 to-do 应用.在这个过程中你会学习到很多 PhoneGap 的知识,例如安装 PhoneGap,编写 Javascript 代码,使用本地存储等等~ 这个教程假设你已经有基本的

用 Swift 开发一个 TODO 应用

背景 相信不少 iOS 程序员对于 Swift 依旧持以观望的态度,一来是这小家伙刚出来没几天,本身还处于完善的阶段:二来是学习的成本较高,看完官方文档怎么也要个几天的时间:三来是反正最近几年很难在工程项目里推广使用,工作又用不到,那我学个锤子呐. 是的,我一开始也是这么想的.直到有一天,我遇到了它:Swift Tutorial - To Do List App.这是 YouTube 上的一个很好地视屏教程,手把手教你如何完成一个 TODO 的应用,功能很简单,就是添加任务和浏览任务.将视屏内容

使用Playground编写第一个Swift程序

从控制台输出"HelloWorld"是我学习C语言的第一步,也是我人生中非常重要的一步.多年后的今天,我仍希望以HelloWorld作为第一步,与大家共同开启一个神奇.瑰丽的世界--Swift编程. 本章以HelloWorld作为切入点,向大家系统介绍如何使用Xcode的Playground编写和运行Swift程序代码. 编写和运行Swift程序有多种方式,我们可以通过在Xcode中创建一个iOS或Mac OS X工程来实现,也可以通过使用Xcode6提供的Playground来实现.

qtday01 ubuntu 下手动编写第一个qt程序

//qt 5.2.1 //1t目录下 //1t.cpp /* 第一个qt程序 */ #include <QApplication> #include<QtWidgets/QLabel> #include<QString> #include<QTextCodec> int main(int argc,char** argv){ /*构造一个对象*/ QApplication app(argc,argv); QTextCodec* coder=QTextCode