Search code examples
iosswiftuitableviewuikituitableviewdiffabledatasource

How to make sections in todo list


I'm doing todo in Swift using diffable data source.

private var todos = [[ToDoItem]]() // my dataSource 
enum Section { // my sections 
    case unfulfilled
    case completed
} 

By clicking on the knockout that is on the task, the task itself should move from the unfulfilled section to completed.

I was also told to use the method with two arrays.

That is, I have my usual datasource, where will todo get to, tell me how to make sure that I have a second branch that is responsible for the second section, or how to solve this problem in general.

An example of my old code:

func configureSnapshot() {
    var snapshot = Snapshot()
    
    if todos.isEmpty { return }
    if todos.count == 1 {
        if todos.first!.first!.isCompleted {
            snapshot.appendSections([.completed])
            snapshot.appendItems(todos.first!, toSection: .completed)
        } else {
            snapshot.appendSections([.unfulfilled])
            snapshot.appendItems(todos.first!, toSection: .unfulfilled)
        }
        
    } else if todos.count == 2 {
        snapshot.appendSections([.unfulfilled, .completed])
        snapshot.appendItems(todos.first!, toSection: .unfulfilled)
        snapshot.appendItems(todos[1], toSection: .completed)
    }
    
    dataSource?.apply(snapshot, animatingDifferences: true)
}

enter image description here

I don't remember the number of their attempts anymore. There were enough of them to tell me to use two arrays.


Solution

  • try this:

    //backing data source
    private var unfulfilledToDos = [ToDoItem]()
    private var completedToDos = [ToDoItem]()
    
    //To-do sections
    enum ToDoSection: Int, CaseIterable {
        case unfulfilled
        case completed
    }
    
    /// call this when you want tableview/collectionview to reload data
    func reloadData(shouldAnimate: Bool) {
        var snapshot = NSDiffableDataSourceSnapshot<ToDoSection, ToDoItem>()
        //if you have no data for that section, tableview/collectionview will create the section with 0 height - thereby rendering the section invisible
        //however, if you have content insets on that section, it will still create those content insets on a section that is not visible. if this doesn't work for your UX, then simply don't append that section below
        snapshot.appendSections(ToDoSection.allCases) 
    
        ToDoSection.allCases.forEach { eachSection in
            switch eachSection {
            case .unfulfilled:
                snapshot.appendItems(unfulfilledToDos, toSection: eachSection)
            case .completed:
                snapshot.appendItems(completedToDos, toSection: eachSection)
            }
        }
    
        dataSource?.apply(snapshot, animatingDifferences: shouldAnimate, completion: { [weak self] in
            //reload of data is completed
        })
    }