0

I have a segmented control that is filled using an enum. I have a table view to show the data of each case. What is the proper way to handle this use-case rather than hardcoding switch-cases for numberOfRowsInSection and cellForRowAt?

let segmentedControl = UISegmentedControl(items: SegmentedControlItems.allCases.map {$0.rawValue}) private enum SegmentedControlItems: String, CaseIterable { case case1 = "Case1" case case2 = "Case2" case case3 = "Case3" } private var arr1 = [Type1]() private var arr2 = [Type2]() private var arr3 = [Type3]() func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch view?.segmentedControl.selectedSegmentIndex { case 0: return case1.count case 1: return case2.count case 2: return case3.count default: return 0 } } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: AssetView.AssetCell.reuseIdentifier, for: indexPath) as? AssetView.AssetCell else { fatalError("Error trying to dequeue cell") } switch view?.segmentedControl.selectedSegmentIndex { case 0: setupCell(case1) case 1: setupCell(case2) case 2: setupCell(case3) default: return UITableViewCell() } return cell } 
3
  • You could have another array of data that you set to the appropriate one when you select a segment. Then use that array to set up the table view as usual. Commented Mar 5, 2022 at 11:35
  • The problem is the arrays are of different types with different attributes Commented Mar 5, 2022 at 15:42
  • Please edit your question and add more details that will help with answering your issue. Commented Mar 5, 2022 at 17:38

2 Answers 2

1

put case1, case2, and case3 in an array. Let's call it cases:

let cases = [case1, case2, case3] 

Then index into that using your segmented control's index:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { guard let selectedItem = view?.segmentedControl.selectedSegmentIndex, selectedItem < cases.count else { fatalError("splat!" } return cases[selectedItem] } 
Sign up to request clarification or add additional context in comments.

4 Comments

any ideas on how could I reuse my enum? Somehow connect the array with it?
Sure. You can create an enum who's raw value is an int, and by default it will have sequential values starting at 0. You can take the rawValue and use it as an index into your array, or for getting/setting a value from/to your segmented control.
Thank you. I guess my main problem is that arrays have different types (I updated my post, please take a look if you can). It means I need an array of type Any that can contain all 3. That would mean I need to blindly cast types in cellForRowAt. Not sure if there is any nice solution for my case. Looks like I still need to use switch-case
Or set up your types to have a shared base type. If they are structs, you can create a common protocol they all conform to, and then have the array contain objects that conform to your protocol.
0

Perfect article about how to use table view with different datasources. It really helped me. https://betterprogramming.pub/uitableview-sections-with-nested-types-27eabb833ad9

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.