Swift 編寫的一個 ToDo App

來源:互聯網
上載者:User

標籤:swift   ios   todo app   notification   

以下所有代碼都是使用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 UIKitprotocol 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 UIKitclass 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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.