How to divide a table view into alphabetised sections if data source and view controllers are separated

Dear all,
I am here to ask some help with the app I am development. It is an apparently simple issue but I have tried about 10 solutions proposed by StackOverflow plus the ones I learned in the Beginning Table Views course and no one worked so I hope you will be able to clarify this for me.

STARTING POINT
The model source is a struct Country { let name: String }. There are many other properties but they are not relevant in the first screen.
I have separated the UITableViewController from the UITableViewDataSource classes to avoid a “massive view controller”.
I have implemented the UISearchBarController from the tutorial found here on the website.
I get data downloaded from a web API in JSON format and parsed into a [Country] object (countries) and copied into a filteredCountries to use the search bar. The downloading and parsing of the JSON happens in a method called loadCountries which is created in the view controller.

WHAT I SEEK
I would like this table view of 250+ elements to look exactly as the Contacts app, that is with the division in sections with localised alphabet letters as section headers.

THE ISSUE
If I try to follow the Documentation of UILocalizedIndexedCollation I cannot find where to put the first part of the code (To prepare the data for a section index, create an indexed-collation object and call section(for:collationStringSelector:) for each model object to be indexed) as I have separated view controller and data source.
Proposed solutions found on the web do not apply to my situation or ask to rewrite everything from the ground up for the data source.
Trying to follow the Beginning Table Views tutorial fails because I would need a class as model and I would like to keep what is working of this embryonal app.

QUESTIONS
How can I apply the UILocalizedIndexedCollation if data source and view controller are separated?
Is there a successor of this class which has been around since iOS 3.0+?
How can I get the desired result without sacrificing the good code written until now?

If you want to check more code, see this SO question: https://stackoverflow.com/questions/57513148/how-can-i-divide-my-table-view-data-in-sections-alphabetically-using-swift-rew

Thank you so much for your help!

Hi @notationmaster,
I am not sure of the code how you have separated this, however what you are after can be added as extensions to the tableview delegate. rather than theorize, if you post part of your code maybe someone could help.

cheers,

In the end I managed to do that in this way:
in the dataSource I created an array of letters by mapping the Unicode characters from 65 to 90
let allLetters = (65...90).map { String(Character(Unicode.Scalar($0))) }, then I created an array of arrays like this var sectionedCountries = [[Country]](repeating: [], count: (65...90).count) (creating it empty made the app crash with index out of range afterwards) and modified all the relevant methods for the table-view.

I used this method because the UILocalizedIndexedCollation way was either not working with my setup with dataSource and viewcontroller separated or I was not able to implement it.

I would be very curious to know how to do this with the extension to the tableview delegate because I have had as many different proposals from as many people who suggested something! From using Dictionary for the data source to using CustomCells to whatever else!

@notationmaster,
If you are after creating an index on the side, then there are a couple of things that you need to consider.

  1. Return the array of titles, or use the UILocalizedIndexedCollection
      func sectionIndexTitles(for tableView: UITableView) -> [String]? {
          return "ABCDEFGHIJKLMNOPQRSTUVWXYZ".map{String($0)}
      } 
  1. When the index is tapped, it returns the index of the section that should house that. so A=0, B=1, C=2 …

So now if you do not have the number of sections that the index returns, you can get an index out of bounds as there is no data for that section, or such a section does not exist.

So you can alternatively return only the characters that exist in your data source, then it will give you the section accordingly.

cheers,

Sorry for not providing full details: after creating that allLetters array I indeed used the sectionIndexTitles methods for that.
In short my solution is working but, I want to specify, UILocalizedIndexedCollation doesn’t at all, which may prove a problem in the future if I want to localise to say … Chinese or other languages … but, until someone gives me a solution that works when you separate data source and view controller, I am stuck there.

Could you tell me what was the way to do it with the extension to the table-view delegate?
Thank you

hi, I am not sure how you have separated your sources and are trying to access it. It’s rather simple but the complexity comes in with the implementation. So if you are trying to solve the problem with the way you are attempting it, cannot suggest anything without seeing what you are attempting.

cheers,

I think I managed it in the end.

Could you just point me to a resource that shows what that alternative method of yours looks like?

Thanks!!

This topic was automatically closed after 166 days. New replies are no longer allowed.