1

I have a UITableView with data coming from NSFetchedResultsController.

Here is my tablewView:

enter image description here

I need to add a row "All types". It also needs to be:

  1. Sortable with all other items
  2. Selectable (Design is now selected)
  3. Selecting "All types" should deselect other rows
  4. Give something to understand that it's an "All types" row when selected

I've read Add extra row to a UITableView managed by NSFetchedResultsController and NSFetchedResultsController prepend a row or section. Given approaches makes impossible to sort data or will look so hacky and produce so much hard-maintailable code, that it will be impossible to change logic and maintain code.

Are there any other good options?

PS. I understand, that my question may sound "broad" and doesn't containt code, but I think it's very common problem.

Community
  • 1
  • 1
Nikita Took
  • 3,980
  • 25
  • 33

1 Answers1

1

I do not think this is a very common problem at all. I can see it seems natural to do what you are trying but lets analyse your situation: What you generally have are 2 arrays of objects which you wish to sort as a single array. Now that is quite a common situation and I believe everyone knows how to solve this issue. You need to create a single array of objects and then sort it.

The way I see it you have 3 options:

  • Fetch all the items, merge the 2 arrays, sort and present them. This is not a very good idea since your memory consumption can be a bit too large if there are a lot of items in the database.
  • Put the extra data into the database and use a fetch result controller as you would normally. This should work good but you will probably need to mark these items so they are later removed or keep it in the database but ignore them where you wish not to display them.
  • Create a temporary database combined with what needs to be fetched from the database and your additional data. This approach is great if your data are meant for read-only in this list (which actually seems to be the case in what you posted). Still it is best if you create some kind of link between the objects. For instance some kind of ID would be great, this way when user selects an object from the second database you simply read the ID and fetch the object from the original database.
Matic Oblak
  • 16,318
  • 3
  • 24
  • 43
  • I don't have two arrays. I just need to add a single line to my tableView – Nikita Took Jul 29 '14 at 05:44
  • Then I fail to see where the issue is. You simply use the delegate methods to add an extra row. You can either get the position of the cell in load time and offset all objects after this position. Or you could apply the insertion on the fly by comparing the requested cell data with custom cell data and offset them if requested data are greater then the custom. – Matic Oblak Jul 29 '14 at 06:39
  • Actually there is a problem. My tableView has some custom logic (for example, selecting "All types" should deselect other rows). If your approach I have to set delegate to my controller and implement didSelectRowForIndexPath with that custom logic. In fact, outer controller doesn't need to know about this logic. What happens if I have 3 tables like this (in different controllers)? I have to copypaste all code or do some weird refactoring – Nikita Took Jul 29 '14 at 06:48
  • You do not need to write this logic multiple times. The table view has both delegate and data source. So didSelectRowForIndexPath is owned by the delegate while the cell insertion is controlled by data source. That means you may have the same data source for multiple delegates or the other way around. Just by the way if your selection is very custom you might want to rather use buttons in the cell and write your own logic.. – Matic Oblak Jul 29 '14 at 06:55
  • I understand, what you are talking about. Actually, I have single datasource object seeding all tableViews now (with different data, of course). But I need different actions in different tableviews' delegate. So I need a delegate to delegate:) The inner delegate will deal with selection, and external one (1 for each cell) will handle touches and perform desired actions. I think this is complex structure and I was looking for a way to solve it in simplier way – Nikita Took Jul 29 '14 at 07:03
  • The table view data source and delegate are usually quite nasty when adding even a smallest additional logic. Try refractoring the code, use multiple files/classes and build a nice interface so your code will look nice and will be maintainable. I suggest you create some sort of data controller wrapper that will feed the data source directly into the table view data source delegate methods. This way you can have something like [wrapper dataForIndexPath:indexPath] in your data source methods and not caring how much logic is behind that method. – Matic Oblak Jul 29 '14 at 07:13