0

hi everyone

i have tow arrays in my project like this

- (void)viewDidLoad
    {
        [super viewDidLoad];
        deviceName = [[NSArray alloc] initWithObjects: @"iPhone", @"Galaxy", @"iPad", @"iMac", @"HTC One", nil];
        companyName = [[NSArray alloc] initWithObjects:@"Apple", @"Samsung", @"Apple", @"Apple", @"HTC", nil];
    }

and i am using this code to modify cells..

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return [searchResult count];
    } else {
        return [deviceName count];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *identifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];

    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
    }

        if ([self.searchDisplayController isActive]) {

            NSString *name = [searchResult objectAtIndex:indexPath.row];
            NSString *company = [companyName objectAtIndex:indexPath.row];
            cell.textLabel.text = [NSString stringWithFormat:@"%@ - %@", name, company];

        } else {

            NSString *name = [deviceName objectAtIndex:indexPath.row];
            NSString *company = [companyName objectAtIndex:indexPath.row];
            cell.textLabel.text = [NSString stringWithFormat:@"%@ - %@", name, company];
        }
    return cell;
}

and i am using this code to searching ..

#pragma mark - UISearchDisplayController delegate methods

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSPredicate *resultPredicate = [NSPredicate
                                    predicateWithFormat:@"SELF contains[cd] %@",
                                    searchText];
    [searchResult release];
    searchResult = [[deviceName filteredArrayUsingPredicate:resultPredicate]retain];
}

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    [self filterContentForSearchText:searchString
                               scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
                                      objectAtIndex:[self.searchDisplayController.searchBar
                                                     selectedScopeButtonIndex]]];
    return YES;
}

at beginning the Cells are ok like this

cell1- iPhone - Apple

cell2- Galaxy - Samaung

...

and when i searching to 'htc' the search is working ok but the cell like this

cell1- HTC One - Apple

...

what can i do to fix that?

Almudhafar
  • 887
  • 1
  • 12
  • 26

1 Answers1

2

You have two separate arrays as table view data source:

deviceName  = [ "iPhone", "Galaxy", "iPad", "iMac", "HTC One"]
companyName = [ "Apple", "Samsung", "Apple", "Apple", "HTC" ]

Then you create a filtered array from deviceName, in your example

searchResult = [ "HTC One"]

In cellForRowAtIndexPath you use the filtered array and the original array companyName, that's why you get the display "HTC One - Apple".

To solve the issue, you should not use two separate arrays as a data source, but a single array of dictionaries, where each dictionary contains the device name and the company name:

allDevices = @[
            @{@"name": @"iPhone", @"company": @"Apple"},
            @{@"name": @"Galaxy", @"company": @"Samsung"},
            ...
            ];

You would filter the array like this:

NSPredicate *resultPredicate = [NSPredicate
                                predicateWithFormat:@"name CONTAINS[cd] %@",
                                searchText];
filteredDevices = [allDevices filteredArrayUsingPredicate:resultPredicate];

so that filteredDevices is also an array of dictionaries, containing name and company for each device. Then, in cellForRowAtIndexPath, you can simply do

NSDictionary *device;
if ([self.searchDisplayController isActive]) {
    device = filteredDevices[indexPath.row];
} else {
    device = allDevices[indexPath.row];
}
NSString *name = device[@"name"];
NSString *company = device[@"company"];
cell.textLabel.text = [NSString stringWithFormat:@"%@ - %@", name, company];

Remark: I have omitted all retain/release calls, as I work with ARC usually.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • @WissamiOS: On which line exactly does the exception occur? – Martin R Nov 10 '13 at 10:59
  • searchResult = [allDevices filteredArrayUsingPredicate:resultPredicate]; (lldb) – Almudhafar Nov 11 '13 at 07:11
  • @WissamiOS: What error do you get on that line? - I have tested the predicate and it worked correctly for me. – Martin R Nov 11 '13 at 08:14
  • this is my project………….https://dl.dropboxusercontent.com/u/3628120/tableSearch.zip – Almudhafar Nov 18 '13 at 06:50
  • @WissamiOS: As I said, my code example assumes ARC (Automatic Reference Counting). Your project does not use ARC, therefore you have to retain `allDevices` and `filteredDevices` (or use "retained properties), otherwise you will get a memory corruption (and that is what happens in your case). - Or better use ARC! – Martin R Nov 18 '13 at 19:30
  • i tired you, but can you see this. i want to add object to array from database, ………….https://dl.dropboxusercontent.com/u/3628120/tableSearching.zip – Almudhafar Nov 21 '13 at 06:56
  • @WissamiOS: Better start a new question. – Martin R Nov 21 '13 at 07:38
  • http://stackoverflow.com/questions/20159048/how-to-add-object-to-nsarray-with-key-from-database – Almudhafar Nov 23 '13 at 05:46