I am making an application in Swift language with UIKIT the application is as follows ToDo List in which I need to output tasks as follows 1 there should be only two sections completed with the button marked and unfulfilled now I have reached the point that I have each new ToDo created in a new section. What to do? Here is my code and what I got as a datasource I have an array inside an array
import UIKit
class TableViewController: UITableViewController {
private var arrExecuteToDo = [String]()
private var todos = [[ToDoItem]]()
private var selectedIndex: Int? // global var for the operation of the row index in the extension
private var todoStatus: [ToDoStatus] = [.completed, .planed]
enum Constants {
static let addTaskIndentifier: String = "addTaskVc"
static let cellIndentifier: String = "ToDoCell"
static let mainStoryboard: String = "Main"
static let secondVC: String = "secondVC"
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == Constants.addTaskIndentifier {
let addTaskVC = segue.destination as? AddTaskViewController // create a link to the second view controller
addTaskVC?.type = .create
addTaskVC?.delegate = self // subscribe it to the delegate of the second controller
}
}
// MARK: - Table view Data Source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
todos[section].count
}
override func numberOfSections(in tableView: UITableView) -> Int {
todos.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: Constants.cellIndentifier,
for: indexPath) as? TableViewCell else { return UITableViewCell() } // cast on your cell
_ = todos[indexPath.row] // pick up the current body by cell index
let todo = todos[indexPath.section]
cell.configureCell(with: todo[indexPath.row]) // config a cell from a cell
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let secondeVC = UIStoryboard(name: Constants.mainStoryboard, bundle: .main).instantiateViewController(
withIdentifier: Constants.secondVC) as? AddTaskViewController else {
fatalError("Unable to Instantiate Quotes View Controller")
}
let todoSection = todos[indexPath.section]
_ = secondeVC.view
secondeVC.configure(with: todoSection[indexPath.row])
secondeVC.type = .edit
secondeVC.delegate = self
navigationController?.pushViewController(secondeVC, animated: true)
selectedIndex = indexPath.row
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { // swipe deleted todo
if (editingStyle == UITableViewCell.EditingStyle.delete) {
todos.remove(at: indexPath.section)
tableView.reloadData()
}
}
}
// MARK: - Extensions
extension TableViewController: AddTaskVCDelegate {
// here we get data from the second view
func didCreateToDo(todo: ToDoItem) {
todos.append([todo]) // add a new element to the array
tableView.reloadData() // reload the table
}
func didUpdateToDo(todo: ToDoItem) {
guard let index = selectedIndex else { return }
todos[index] = [todo]
tableView.reloadData()
}
func didDeleteToDo() { // add protocol method for delete todo
guard let index = selectedIndex else { return }
todos.remove(at: index)
tableView.reloadData()
}
}
I thought that the problem is how I display the sections of the table, but I did not find how to change it as I need it
Because you create a separate section for each task in your code, a new section is created for each new ToDo. You say you only need two parts: "Completed" and "Uncompleted". To fix this situation, you need to use a separate array for both parts.
Here are the steps you need to do:
1-) Define the todos array as a single array of type [ToDoItem]. This series will include completed and unfinished tasks.
2-) Remove the todoStatus array because it will no longer be associated with any partition.
3-) Let the numberOfSections function return 2 as a constant. This value can remain constant as there will always be only two partitions.
}
4-) Update the tableView(_:numberOfRowsInSection:) function. Filter the todos array accordingly to return the number of tasks in each section.
}
5-) Update the cellForRowAt function. Based on the section number and line number, get the corresponding ToDo and configure the cell.
}
With these changes, you will keep all the ToDo items within the todos array and filter the related tasks in each section.