Swift 书面 ToDo App
下面的代码是使用的全部Xcode Version 6.0.1 (6A317)书面。
因为当使用团队开发stroyboard在并购的诸多不便的时间,所有或使用.xib该文件准备ToDo App.
想要实现的功能:TableView 够添加待做选项。并依照时间先后排序,能够实现删除。到点通知功能。
想要实现的效果例如以下:
步骤:
1、新建一个基于Singal View Application 的project,然后删掉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 添加一个 ‘+’ button,用来给用户添加待做选项
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 easy,新建一个 .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上来。须要的到这里拿。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
Swift 书面 ToDo App的更多相关文章
- 用Swift语言做App开发之单元测试
作为一个有质量保障的应用程序,当然少不了单元测试:Swift开发的App也亦如此,此文将以一个简单的实例来介绍Swift中的单元测试. 这里我们使用XCode模版自带的XCTest框架,此框架包含了一 ...
- 21个高质量的Swift开源iOS App
原文:21 Amazing Open Source iOS Apps Written in Swift 对Swift初学者来说,学习开源项目,阅读源码是个不错的方法.在这篇文章中,基于对代码质量和排名 ...
- Meteor ToDo App实例
在本章中,我们将创建一个简单的待办事项应用程序. 第1步 - 创建应用程序 打开命令提示符,运行以下命令 - C:\Users\Administrator\Desktop>meteor crea ...
- react native 实现TODO APP
前端有一个todo app非常适合入门练手 react-native 实现todo app:https://github.com/nwgdegitHub/TODO_RN.git
- 写一个TODO App学习Flutter本地存储工具Moor
写一个TODO App学习Flutter本地存储工具Moor Flutter的数据库存储, 官方文档: https://flutter.dev/docs/cookbook/persistence/sq ...
- .NET 跨平台应用开发动手教程 |用 Uno Platform 构建一个 Kanban-style Todo App
作者:Steven Giesel 翻译:Alan Wang 校对:李卫涵 – 微软 MVP 排版:Rani Sun 有什么比参考包含分步说明和代码示例的动手教程更好的学习新技术的方式呢?当你完成或 f ...
- 使用 Realm 和 Swift 创建 ToDo 应用
原文出处: HOSSAM GHAREEB 译文出处:Prayer’s blog(@EclipsePrayer) 智能手机的快速发展的同时,涌现出了很多对开发者友好的开发工具,这些工具不仅使得开发变 ...
- Building gRPC Client iOS Swift Note Taking App
gRPC is an universal remote procedure call framework developed by Google that has been gaining inter ...
- 【转载】谷歌酝酿将苹果Swift作为安卓APP主要开发语言
TNW中文站 4月8日报道 安卓操作系统的软件开发语言是Java,而在过去几年中,有关Java的版权,谷歌(微博)和甲骨文之间发生了长期的诉讼.最新外媒消息称,谷歌正在考虑将苹果开发的Swift作为未 ...
随机推荐
- 《effective java》读书札记第三条用私有构造器或者枚举类型强化Singleton属性
Singleton指只被实例化一次的类.一般用来搞那些创建很耗资源或者要求系统中只能有一个实例的类. 这个很经常使用.记得曾经实习面试的时候就有这个面试题. 一般採用的方法是将构造器私有化,然后提供一 ...
- Leetcode 细节实现 Set Matrix Zeroes
Set Matrix Zeroes Total Accepted: 18139 Total Submissions: 58671My Submissions Given a m x n matrix, ...
- Java如何检查List<String> 里是否有想要的字符串?
List<String> test = new ArrayList<String>(); test.add("a"); test.add("b&q ...
- Mac OS X在建筑Python科学计算环境
经验(比如这篇日志:http://blog.csdn.net/waleking/article/details/7578517).他们推荐使用Mac Ports这种软件来管理和安装全部的安装包.依照这 ...
- java日历程序版本
//MainFrame.java package com.huowolf.myCalender; import java.awt.BorderLayout; import java.awt.Color ...
- 一个测试SQL2005数据库连接JSP档
在这里,在SQL 2005中间InterLib数据库案例.得到InterLib/tb_booktype目录. 的影响,如下面的: watermark/2/text/aHR0cDovL2Jsb2cuY3 ...
- windows phone (26) ApplicationBar应用程序栏
原文:windows phone (26) ApplicationBar应用程序栏 在应用程序中,如果需要几个按钮或者菜单来执行一些普通的命令,就应该考虑使用ApplicationBar,因为silv ...
- IM设计与实现的系统模块的聊天记录
到非常多开发IM系统的朋友都想实现聊天记录存储和查询这一不可或缺的功能,这里我就把自己前段时间为傲瑞通(OrayTalk)开发聊天记录模块的经验分享出来,供须要的朋友參考下. 一.整体设计 1.存储位 ...
- 通过action 跨进程启动activity
在一些场景中我们需要从一个进程启动另外的一个应用的activity,这有什么好办法? 这里介绍一种方法,通过自定义 action 通过filter来启动. 如果你需要启动一个你自己写的另一个app的a ...
- OCP-1Z0-051-名称解析-文章7称号
7. Which two statements are true regarding the USING and ON clauses in table joins? (Choose two.) A ...