This seems like it should be straight forward. Technically I can make this work, but if I want to perform certain UI animations, (using deleteRowsAtIndexPaths:withRowAnimation:) things get hairy. It seems as though the datasource and UI are fighting over who should delete first. Then I have to artificially keep data around for the UI update.
My current setup:
In my model:
- Create a multidimensional NSArray to hold my data. (each sub array represents a section).
- Place a NSDictionary in each section array to represent the data for an individual cell.
In my View Controller:
- Create a multidimensional NSArray to hold my Cell Controllers (mimicking the data structure).
- Assign each model dictionary to an ivar in the appropriate Cell Controller.
- Hook up the data to the cell
This gets my UITableView on screen with cells properly displayed. Now if I want to filter the data in the table I do the following:
In my model:
- Create an instance of NSPredicate.
- Filter each subarray of the multidimensional array.
- Set a flag in each dictionary that is within the results of the filtered array.
In my View controller:
- I create a new Multidimensional NSArray. This array will hold the cell controllers of the "filtered data"
- Loop through the current Multidimensional Controller array. Add it to the new "filtered array if it's model's flag is set.
- Replace the unfiltered Controller array with the new one.
- Update the table.
This also works very well. As long as I don't mind the UI updating instantaneously. If I want to delete rows with animation, I must pass those indexes to the table to be deleted.
To accomplish this, I add a few more steps to the view controller:
In my View controller:
- I create a new Multidimensional NSArray. This array will hold the cell controllers of the "filtered data"
- Loop through the current Multidimensional Controller array. Add it to the new "filtered array if it's model's flag is set.
- Create a new NSArray to hold indexes to be deleted.
- Loop through the current Multidimensional Controller array. Add its cell's index to the "toBeDeleted" array if its model's flag is NOT set.
- Replace the unfiltered Controller array with the new one.
- perform deleteRowsAtIndexPaths:withRowAnimationn.
So far this method doesn't work the greatest. I am having issues deleting the rows with edge cases (empty sections and all visible cells being deleted).
This made me think maybe my methodology is flawed. Has anyone implemented this in an app? How did you solve this? Do your row animations work?