views:

1286

answers:

3

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:

  1. Create a multidimensional NSArray to hold my data. (each sub array represents a section).
  2. Place a NSDictionary in each section array to represent the data for an individual cell.

In my View Controller:

  1. Create a multidimensional NSArray to hold my Cell Controllers (mimicking the data structure).
  2. Assign each model dictionary to an ivar in the appropriate Cell Controller.
  3. 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:

  1. Create an instance of NSPredicate.
  2. Filter each subarray of the multidimensional array.
  3. Set a flag in each dictionary that is within the results of the filtered array.

In my View controller:

  1. I create a new Multidimensional NSArray. This array will hold the cell controllers of the "filtered data"
  2. Loop through the current Multidimensional Controller array. Add it to the new "filtered array if it's model's flag is set.
  3. Replace the unfiltered Controller array with the new one.
  4. 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:

  1. I create a new Multidimensional NSArray. This array will hold the cell controllers of the "filtered data"
  2. Loop through the current Multidimensional Controller array. Add it to the new "filtered array if it's model's flag is set.
  3. Create a new NSArray to hold indexes to be deleted.
  4. Loop through the current Multidimensional Controller array. Add its cell's index to the "toBeDeleted" array if its model's flag is NOT set.
  5. Replace the unfiltered Controller array with the new one.
  6. 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?

A: 

Not to make matters worse, but have you tried NSPredicate on an actual device?

I found that NSPredicate worked on the Simulator, but much like NSXMLDocument, wasn't available on the device itself (2.2.1).


update: Given that NSPredicate is available, all I can add is that I've had unpredictable results with deleteRowsAtIndexPaths:withRowAnimation as well - I had to settle for calling reloadData and having a non-animated transition.

Fortunately, since I have a highly "subtractive" filter in my app, there's typically a lot of movement, so it's obvious to the user that something has happened.

In your case where visible changes are potentially non-obvious, I suspect that from a usability perspective, it might be sufficient simply to use an animated UIImageView moving from north to south across the UITableView area. (a challenge in it's own right, unfortunately).

This would have the added bonus of confirming the filter's application to the user even if no visible changes occurred.

Glenn Barnett
This isn't available on 2.2.1, you are right. But is available on [redacted].
Corey Floyd
Interesting -- thanks.
Glenn Barnett
A: 

I have implemented this using the design which I outlined here (personal blog post)

I will post some specific code when I clean it up and make it a bit more generic.

Corey Floyd
A: 

Hi Corey Did you get this working? Can you provide some example code? I'd be interested in helping get a generic version going. Many thanks Phil

Phil Patch