制作一个仿任务清单的App,主要为了练习TableViewController。
//row -> indexPath
let indexPath = IndexPath(row: row, section: 0)
//indexPath -> row
let row = indexPath.row
//indexPath -> cell
let cell = tableView.cellForRow(at: indexPath)
//cell -> indexPath
let indexPath = tableView.indexPath(for: cell)
//row -> cell
let indexPath = IndexPath(row: row, section: section)
let cell = ableView.cellForRow(at: IndexPath)
//cell -> row
let row = tableView.indexPath(for: cell)!.row
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
}
}
// 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
// Configure the cell...
cell.checkMark.text = todos[indexPath.row].checked ? "√" : ""
cell.todo.text = todos[indexPath.row].name
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: false)
}
protocol TodoDelegate {
func didAdd(name: String) -> Void
}
@IBAction func done(_ sender: Any) {
if let name = todoInput.text, !name.isEmpty {
delegate?.didAdd(name: name)
}
navigationController?.popViewController(animated: true)
}
extension TodosController: TodoDelegate {
func didAdd(name: String) {
todos.append(Todo(name: name, checked: false))
let indexPath = IndexPath(row: todos.count - 1, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)
}
}
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.
if segue.identifier == "addTodo" {
let vc = segue.destination as! TodoController
vc.delegate = self
}
}
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.
let vc = segue.destination as! TodoController
vc.delegate = self
if segue.identifier == "editTodo" {
let cell = sender as! TodoCell
//通过cell获取indexPath
row = tableView.indexPath(for: cell)!.row
vc.name = todos[row].name
}
}
navigationItem.title = "edit"
protocol TodoDelegate {
func didAdd(name: String) -> Void
func didEdit(name: String) -> Void
}
@IBAction func done(_ sender: Any) {
if let name = todoInput.text, !name.isEmpty {
if self.name != nil {
delegate?.didEdit(name: name)
} else {
delegate?.didAdd(name: name)
}
}
navigationController?.popViewController(animated: true)
}
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
}
navigationItem.leftBarButtonItem = editButtonItem
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
editButtonItem.title = isEditing ? "Finish" : "Edit"
}
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: false)
}
}
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
todos.remove(at: indexPath.row)
// 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 func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
return "delete"
}
@IBAction func batchDelete(_ sender: Any) {
let indexPaths = tableView.indexPathsForSelectedRows
if let indexPaths = indexPaths {
for indexPath in indexPaths {
todos.remove(at: indexPath.row)
}
tableView.beginUpdates()
tableView.deleteRows(at: indexPaths, with: .automatic)
tableView.endUpdates()
// tableView.reloadData()//没有动画效果
}
}
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
//move data
let todo = todos.remove(at: fromIndexPath.row)
todos.insert(todo, at: to.row)
//update view
tableView.moveRow(at: fromIndexPath, to: to)
tableView.reloadData()
}
func saveData() -> Void {
do {
let data = try JSONEncoder().encode(todos)
UserDefaults.standard.set(data, forKey: "todos")
} catch {
print(error)
}
}
if let data = UserDefaults.standard.data(forKey: "todos"){
do{
todos = try JSONDecoder().decode([Todo].self, from: data)
}catch {
print(error)
}
}