Todos App

Todos的功能:

添加数据
更改数据
删除数据
批量删除数据
移动数据

Main.storyboard:
删除原本的ViewController 创建一个Table View Controller,并且钩上Is Initial View Controller

在这里插入图片描述
在这里插入图片描述
删除左栏的ViewController,在Cocoa Touch Class添加一个TableViewController,命名为TodosController并整理为MVC格式
在这里插入图片描述
Model内创建Todo结构体

import Foundation

struct Todo {
    var name = ""
    var checked = false
}

实例化Todo

class TableViewController: UITableViewController {
    var todos = [
        Todo(name: "吃大象", checked: false),
        Todo(name: "开飞机", checked: false),
        Todo(name: "造坦克", checked: false),
        Todo(name: "坐火箭", checked: false),
        Todo(name: "炸学校", checked: false)
    ]

设置tableview的段数和行数

override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 0
    }

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

创建TableViewCell
在cell里面增加两个label
在这里插入图片描述
与cell连接

@IBOutlet weak var checkMark: UILabel!
@IBOutlet weak var Todo: UILabel!

更改cell的Accessory属性
将todos里面的Todo依次放入cell中:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "todo", for: indexPath) as! TodoCell
        cell.checkMark.text = todos[indexPath.row].checked ? "√" : ""
        cell.todo.text = todos[indexPath.row].name
        // Configure the cell...

        return cell
    }

效果:
在这里插入图片描述

添加点击后打勾与取消打勾效果

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        //更改数据
        todos[indexPath.row].checked = !todos[indexPath.row].checked
        //更新视图
        let cell = tableView.cellForRow(at: indexPath) as! TodoCell
        cell.checkMark.text = todos[indexPath.row].checked ? "√" : ""
        tableView.deselectRow(at: indexPath, animated: true)
        
    }
    

实现添加功能
创建TodoController,添加一个text
在这里插入图片描述

用Navigation Controller连接,并添加一个bar button item,与新的controller连接
在这里插入图片描述

设置新的tableview controller的行数列数

override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return 1
    }

用protocol实现反向传值

protocol TodoDelegate {
    func didAdd(name: String)
}

class TodoController: UITableViewController {
    var delegate :TodoDelegate?
    

按完成时调用didAdd函数,并且弹出界面

@IBAction func done(_ sender: UIBarButtonItem) {
        if let name = todoInput.text,!name.isEmpty {
            delegate?.didAdd(name: name)
        }
        navigationController?.popViewController(animated: true)
    }

TodosController里面实现TodoDelegate的didAdd函数

extension TodosController:TodoDelegate {
    func didAdd(name: String) {
        //添加数据
        todos.append(Todo(name: name, checked: false))
        //更改视图
        let indexPath = IndexPath.init(row: todos.count - 1, section: 0)
        tableView.insertRows(at: [indexPath], with: .automatic)
    }
    
}

实现跳转

  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "addTodo" {
            let vc = segue.destination as! TodoController
            vc.delegate = self
        }
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }

效果:
在这里插入图片描述
在这里插入图片描述

实现编辑的功能

增加编辑函数

protocol TodoDelegate {
    func didAdd(name: String)
    func didEdit(name: String)
}

添加变量保留需要编辑的cell的内容

var name : String?

当name为空时调用编辑函数

@IBAction func done(_ sender: UIBarButtonItem) {
        if let name = todoInput.text,!name.isEmpty {
            if self.name != nil {
                delegate?.didEdit(name: name)
            }else{
                delegate?.didAdd(name: name)
            }
        }
        navigationController?.popViewController(animated: true)
    }

每次页面出现当name不为空时让navigation的title变为编辑任务

override func viewDidLoad() {
        super.viewDidLoad()
        
        todoInput.becomeFirstResponder()
        todoInput.text = name
        if name != nil {
            navigationController?.title = "编辑任务"
        }
        
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem
    }

实现跳转

  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "addTodo" {
            let vc = segue.destination as! TodoController
            vc.delegate = self
        }else if segue.identifier == "editTodo" {
            let vc = segue.destination as! TodoController
            let cell = sender as! TodoCell
            let row = tableView.indexPath(for: cell)!.row
            vc.name = todos[row].name
            vc.delegate = self
        }
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }

实现编辑函数

func didEdit(name: String) {
        todos[row].name = name
        let indexPath = IndexPath(row: row, section: 0)
        let cell = tableView.cellForRow(at: indexPath) as! TodoCell
        cell.todo.text = name
    }

实现效果:
在这里插入图片描述
在这里插入图片描述

实现删除数据

实现删除

 override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // Delete the row from the data source
            //删除数据
            todos.remove(at: indexPath.row)
            //更新视图
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }

将Delete改名为删除

override func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
        return "删除"
    }

效果:
在这里插入图片描述

实现批量删除

添加选中的按钮

override func viewDidLoad() {
        super.viewDidLoad()
        
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        navigationItem.leftBarButtonItem = self.editButtonItem
        editButtonItem.title = "编辑"
    }

更改选中的名字为中文

override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: animated)
        editButtonItem.title = isEditing ? "完成" : "编辑"
    }

添加删除按钮

在这里插入图片描述
实现删除按钮的功能

 @IBAction func batchDelegate(_ sender: UIBarButtonItem) {
        if let indexPaths = tableView.indexPathsForSelectedRows {
            for indexPath in indexPaths {
                todos.remove(at: indexPath.row)
            }
            tableView.beginUpdates()
            tableView.deleteRows(at: indexPaths, with: .automatic)
            tableView.endUpdates()
        }
    }

实现效果
在这里插入图片描述

实现移动数据

override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
        let todo = todos[fromIndexPath.row]
        todos.remove(at: fromIndexPath.row)
        todos.insert(todo, at: to.row)
        
        tableView.reloadData()
    }

最后完成代码:
TodosController:

import UIKit

class TodosController: UITableViewController {

    var row = 0
    var todos = [
        Todo(name: "吃大象", checked: false),
        Todo(name: "开飞机", checked: false),
        Todo(name: "造坦克", checked: false),
        Todo(name: "坐火箭", checked: false),
        Todo(name: "炸学校", checked: false)
    ]
    
    @IBAction func batchDelegate(_ sender: UIBarButtonItem) {
        if let indexPaths = tableView.indexPathsForSelectedRows {
            for indexPath in indexPaths {
                todos.remove(at: indexPath.row)
            }
            tableView.beginUpdates()
            tableView.deleteRows(at: indexPaths, with: .automatic)
            tableView.endUpdates()
        }
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        navigationItem.leftBarButtonItem = self.editButtonItem
        editButtonItem.title = "编辑"
    }
    override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: animated)
        editButtonItem.title = isEditing ? "完成" : "编辑"
    }


    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

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

    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "todo", for: indexPath) as! TodoCell
        cell.checkMark.text = todos[indexPath.row].checked ? "√" : ""
        cell.todo.text = todos[indexPath.row].name
        // Configure the cell...

        return cell
    }
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if !isEditing {
            //更改数据
            todos[indexPath.row].checked = !todos[indexPath.row].checked
            //更新视图
            let cell = tableView.cellForRow(at: indexPath) as! TodoCell
            cell.checkMark.text = todos[indexPath.row].checked ? "√" : ""
            tableView.deselectRow(at: indexPath, animated: true)
        }
        
    }
    
    

    
    // Override to support conditional editing of the table view.
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        
        // Return false if you do not want the specified item to be editable.
        return true
    }
    

    
    // Override to support editing the table view.
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // Delete the row from the data source
            //删除数据
            todos.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
    override func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
        return "删除"
    }
    

    
    // Override to support rearranging the table view.
    override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
        let todo = todos[fromIndexPath.row]
        todos.remove(at: fromIndexPath.row)
        todos.insert(todo, at: to.row)
        
        tableView.reloadData()
    }
    

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the item to be re-orderable.
        return true
    }
    */

    
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "addTodo" {
            let vc = segue.destination as! TodoController
            vc.delegate = self
        }else if segue.identifier == "editTodo" {
            let vc = segue.destination as! TodoController
            let cell = sender as! TodoCell
            let row = tableView.indexPath(for: cell)!.row
            vc.name = todos[row].name
            vc.delegate = self
        }
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    

}
extension TodosController:TodoDelegate {
    func didAdd(name: String) {
        //添加数据
        todos.append(Todo(name: name, checked: false))
        //更改视图
        let indexPath = IndexPath.init(row: todos.count - 1, section: 0)
        tableView.insertRows(at: [indexPath], with: .automatic)
    }
    func didEdit(name: String) {
        //添加数据
        todos[row].name = name
        //更改视图
        let indexPath = IndexPath(row: row, section: 0)
        let cell = tableView.cellForRow(at: indexPath) as! TodoCell
        cell.todo.text = name
    }
    
    
}

TodoCell:

import UIKit

class TodoCell: UITableViewCell {

    @IBOutlet weak var checkMark: UILabel!
    @IBOutlet weak var todo: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

TodoController:

import UIKit
protocol TodoDelegate {
    func didAdd(name: String)
    func didEdit(name: String)
}

class TodoController: UITableViewController {
    var delegate :TodoDelegate?
    var name : String?
    
    @IBOutlet weak var todoInput: UITextField!
    
    @IBAction func done(_ sender: UIBarButtonItem) {
        if let name = todoInput.text,!name.isEmpty {
            if self.name != nil {
                delegate?.didEdit(name: name)
            }else{
                delegate?.didAdd(name: name)
            }
        }
        navigationController?.popViewController(animated: true)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        todoInput.becomeFirstResponder()
        todoInput.text = name
        if name != nil {
            navigationController?.title = "编辑任务"
        }
        
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return 1
    }

    /*
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)

        // Configure the cell...

        return cell
    }
    */

    /*
    // Override to support conditional editing of the table view.
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return true
    }
    */

    /*
    // Override to support editing the table view.
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // Delete the row from the data source
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
    */

    /*
    // Override to support rearranging the table view.
    override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {

    }
    */

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the item to be re-orderable.
        return true
    }
    */

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}

Main.storyboard上的视图:
在这里插入图片描述

发布了6 篇原创文章 · 获赞 8 · 访问量 350

猜你喜欢

转载自blog.csdn.net/qq_44864362/article/details/100182498
app
今日推荐