0

I have a tableView and I'm tracking which rows were selected by adding the row's indexPath to an array and then adding a checkmark.

I'm iterating through that array using this bit of code in my cellForRowAtIndexPath method and it works like a charm:

for (NSIndexPath * element in indexArray)
    if ([indexPath compare:element] == NSOrderedSame) { 
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }

However, I'm also taking the value of that row and putting it into another array for other purposes. I figured I could simplify my code if I just used this second array for both cases but I don't understand how I'd rewrite the above code. I get the concept but the above code uses an indexPath comparison and I'll need to compare a string to the array.

It's that 'if' line that I don't know how to change.

for (NSString *element in valueArray) {
    if ([indexPath compare:element] == NSOrderedSame) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
}  

Thoughts? Thanks.

Edit With More Info

My array contains 400 unique items that will not change. Adding their indexPath to my array and iterating through it to add checkmarks works fine. The reason why I want iterate using the array's string values instead is because I want to add a searchBar to the tableView.

After I add that searchBar, when I do a search, the searchResultsTableView truncates my 400 unique items down to the few that match that search - so we're down to one or a few rows in my searchResultsTableView. Now let's say we select the first row that was returned in the search - my code then adds that row's indexPath to my indexArray to keep track of checkmarks. It would add the index 0,0.

But then when we cancel out of Search mode, the first row 0,0 would be checked in my tableView because we selected 0,0 in searchResultsTableView - even though the row we selected would be way down the list in the full tableView. See where I'm going? So my thought was to track the row's string instead of it's indexPath to alleviate this problem.

More clear?

Selch
  • 131
  • 1
  • 10
  • 1
    Wouldn't that fail if you have 2 different rows with the same value? – Martin R Oct 23 '12 at 15:36
  • Your first loop can be simplified to `if ([indexArray containsObject:indexPath]) ...` – Martin R Oct 23 '12 at 15:43
  • Yes, it would fail but my array contains 400 unique values that won't change. – Selch Oct 23 '12 at 16:05
  • OK, I see. But I don't see how you could map a string to a row number. You could use an array of dictionaries where each dictionary contains the value and the selected state of the row if you want to "bundle" the information for each row. (Compare Chris F's answer.) – Martin R Oct 23 '12 at 16:12

2 Answers2

0

You can create a c struct with both string and index values, and wrap this into an NSValue object, and then put the object in the NSArray? You can then modify your for() loop and if() clause to use the NSValue? See How to wrap a Struct into NSObject

Community
  • 1
  • 1
Chris F
  • 14,337
  • 30
  • 94
  • 192
0

You could use an array of (mutable) dictionaries as data source for the table view. Each dictionary contains the text value and the selection state (as NSNumber) for one row. (I'm assuming here that your table view has only one section).

Then in cellForRowAtIndexPath you can do something like

NSDictionary *d = [dataArray objectAtIndex:indexPath.row];
NSString *value = [d objectForKey:@"value"];
BOOL selected = [[d objectForKey:@"selected"] boolValue];

and set the cell's content and accessory type accordingly.

To change the selection state:

NSDictionary *d = [dataArray objectAtIndex:indexPath.row];
BOOL selected = [[d objectForKey:@"selected"] boolValue];
[d setObject:[NSNumber numberWithBool:!selected] forKey:@"selected"];

Now for your search you would create a filtered subset of that array. But because the filtered array references the same dictionaries, the selection state for each entry is preserved when you change the search text or finish the search.

Of course you would have to use the filtered array in the above methods when the search is active.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382