1

I'm not sure if this is possible I have looked around, checked online and finally posting this question here what I'm trying to do is,

I have 3 sections in UITableView but third section only appears if my data model is updated

enum Section: Int {
    case title, accounts, pending, total
}

in my numberOfSections I currently have,

return (pendingDataModel != nil) ? 3 : 2

is it possible to handle this in computed property of enum? like based on the above condition adding and hiding the case pending so that I can only use Section.total.rawValue to get my section's count?

Edit: I have found this answer but this isn't what I want Adding a case to an existing enum with a protocol

Arun Kumar
  • 471
  • 1
  • 4
  • 14
  • `Section.total.rawValue` would be a bad idea, even if did what you want. You want the total number of sections. Nothing about `Section.total.rawValue` makes that clear, so it would be really confusing to see the `rawValue` of some (seemingly) arbitrary being used for a count. – Alexander Jan 14 '20 at 20:33
  • Assuming you have some kind of `FooModel` type, and a `FooTableViewDataSource` that's used to present it, the appropriate place for code like this (to determine the number of sections) is in a computed property on `FooTableViewDataSource`, which accesses the `fooModel` and determines the right number of sections. – Alexander Jan 14 '20 at 20:35
  • @Alexander-ReinstateMonica I agree `Section.total.rawValue` is confusing and not the best practice but can you give an example of "computed property on FooTableViewDataSource, which accesses the fooModel and determines the right number of sections" ? – Arun Kumar Jan 14 '20 at 20:39
  • I don't have time to cook up an example, but I'm saying that what you're doing is essentially the right thing. The purpose of a `FooTableViewDataSource` (which conforms to `UITableViewDataSource`) is to wrap a piece of data (your `fooModel: FooModel`) and adapt it to fit into a table view. That requires it to calculate the number of sections that are needed to reperesent the `fooModel`. The correct place to calculate that is in the `FooTableViewDataSource`. It's not the purpose of a section enum to calculate that. – Alexander Jan 15 '20 at 00:03
  • If your `FooTableViewDataSource` gets toooo hairy, then it might be worth while to extract out a seperate `presenter` object, which contains the helper methods needed to extract/derive various user-facing representations of the data in a `fooModel`. – Alexander Jan 15 '20 at 00:04

2 Answers2

1

One idea is to use a struct as an intermediary between data and the view controller. This struct can be created and used by a method like tableview's cell count; each time your view needs to know its layout, it constructs itself using whether or not there exists pending data.

enum Section: Int, CaseIterable {
    case title, accounts, pending, total
}

struct SectionData {

    var sections: [Section]

    init(hasPendingData: Bool) {
        if (hasPendingData) {
            sections = Section.allCases
        } else {
            sections = [.title, .accounts]
        }
    }

}

class MyViewController: UIViewController {

    var pendingModelData: Data?

    func sectionCount() -> Int {
        return SectionData(hasPendingData: pendingModelData != nil).sections.count
    }

}

Going a step further, you could use didSet on pendingModelData to update the view displaying sections.

jnblanchard
  • 1,182
  • 12
  • 12
0

Enumerations with a nested enumeration can be a solution

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        pendingDataModel != nil ?
            Section.Count.hasPendingRecords.rawValue : Section.Count.noPendingRecords.rawValue
    }

enum Section: Int {
    case title, accounts, pending, total

    enum Count: Int {
        case hasPendingRecords = 3
        case noPendingRecords = 2
    }
}
Blazej SLEBODA
  • 8,936
  • 7
  • 53
  • 93