iPhone app returns array item 0 during search every time (confused on indexPath.row)

dalearyous

[H]ard|Gawd
Joined
Jun 21, 2008
Messages
1,922
so i have an array that is currently searchable. when you load the app it loads up the information in a tableview with a list of the (in my case) names in the array. if you click on any one of the names it loads the correct detail view. the search works just fine too. when you begin typing it narrows down the searchs and displays what is left below the search bar. cool. however, lets say there are three names: Bob, Carl, Devin. if you start typing D, the search narrows it down to just Devin. if you click on Devin it doesn't load Devin's detail view, it loads Bob's because bob is the first one in the array. any idea how to fix this? i would be happy to send my project to someone or provide code snippets here

from what i have read i think that i am not retaining the original value of indexPath.row (prior to the search). cause when i do the search it uses indexPath.row again but now any of the three is on the first line...hence row 0. (because the search has narrowed it down to just 1 item which is at position 0 now)

make sense?
 
Last edited:
The indexPath passed in to willSelect or didSelect is the index path from the list of search results when searching. You're likely grabbing the item in the full array of items instead of indexing into the array of search results, which should be a separate data structure.

Try doing something like this:
Code:
if (aTableView == self.tableView) {
    //Index into full array of items
} else {
    //Index into search results array
}

A real example where a fetched results controller is used to load the data but search results are in a separate array (b/c the doc says you shouldn't change the predicate on a fetched results controller after initialization):

Code:
if (aTableView == self.tableView) {
	foo = [self.fetchedResultsController objectAtIndexPath:indexPath];
} else {
	foo = [self.searchResults objectAtIndex:indexPath.row];
}

where aTableView is the local tableView reference passed into the delegate method and self.tableView is obviously a reference to the primary (non-search) table view.
 
Last edited:
this is what i have:

Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIViewController *detailsViewController = [[UIViewController alloc] init];
	/*
	 If the requesting table view is the search display controller's table view, configure the next view controller using the filtered content, otherwise use the main list.
	 */
	Physician *physician = nil;
	if (tableView == self.searchDisplayController.searchResultsTableView)
	{
        physician = [self.filteredListContent objectAtIndex:indexPath.row];
    }
	else
	{
        physician = [self.listContent objectAtIndex:indexPath.row];
    }
	detailsViewController.title = physician.name;
	
	NSString* physicianName = [tmpImages objectAtIndex:indexPath.row];
	UIImage* physicianImage = [UIImage imageNamed:physicianName];
	UIImageView* physicianImageView = [[UIImageView alloc] initWithImage:physicianImage];
	physicianImageView.frame = self.view.bounds;
	[detailsViewController.view addSubview:physicianImageView];
	[physicianImageView release];
	
	
    [[self navigationController] pushViewController:detailsViewController animated:YES];
    [detailsViewController release];
}
 
Can you share the code that populates filteredListContent? Are you clearing filteredListContent prior to each search?
 
Code:
- (void)filterContentForSearchText:(NSString*)searchText
{
	[[[self filteredPhysicians] physician] removeAllObjects];
	
	//NSLog(@"%@",searchText);
	for (int i = 0; i < [PhysicianModel getNumberOfPhysicians]; i++)
	//for (physicianModel *temp in )
	{
		
		NSComparisonResult result =  0;
		result = [[[PhysicianModel physician] objectAtIndex:i] compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
            if (result == NSOrderedSame)
			{
				
				[[[self filteredPhysicians] physician] addObject:[[PhysicianModel physician] objectAtIndex:i]];
				[[[self filteredPhysicians] physicianImages] addObject:[[PhysicianModel physicianImages] objectAtIndex:i]];
				
            }
		
	}
	
}
 
Ok, still not enough info (for example, I don't understand your model at all but let's go with it). I would look up NSPredicate and the filteredArrayUsingPredicate: method on NSArray.

This example isn't a complete sample and isn't directly applicable (since I don't know your model) but it assumes the input is an array of physicians that have firstName and lastName properties. It returns a filtered array of physicians that have a first or last name matching the searchString. The predicate below would match "bobby," for example.

If you're using core data, for example, then you would perform a fetch with this predicate. You would have the filtered array to be an instance variable so you could access it from the tableview delegate methods. I'm *really* puzzled by this line:

Code:
[[[self filteredPhysicians] physician] removeAllObjects];

Why aren't you clearing your entire filtered list of physicians? Or are you and it's really unclear?

StackOverflow is seriously your friend for iOS stuff, btw.

Code:
NSString *searchString = @"bob";
NSArray *physicians = ...;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstName CONTAINS[cd] %@ OR lastName CONTAINS[cd] %@", searchString, searchString];
NSArray *filteredArray = [physicians filteredArrayUsingPredicate:predicate];
 
Back
Top