Search code examples
iosobjective-cuitableviewuisearchdisplaycontroller

Search in a tableView Cell issue


I am using xcode 5 and want to search a tableView data. I used "Search Bar & Search Display Controller" for "searching", "CustomCell" for "tableCell" and all the data are parsing from a remote server by NSXMLParsing. All data are showing with their corresponding image without any problem but some how my search option doesn't work properly. I do the same code for a single array searsing and it was working. But here it isn't. At the time of searching it is crashed. Here is my code:

-(void)loadData
{
    countryParser = [[CountryParser alloc] loadXMLByURL:@"http://www.avowstudio.com/iOS/PartProject/iOS7/XMLParsingWithCustomeCell/XMLFiles/XMLParsingWithCustomCell.xml"];

    countryArray = [countryParser countryArray];

    displayItems = [[NSMutableArray alloc] initWithArray:countryArray];

    [self.countryTableView reloadData];
    [activityIndicator stopAnimating];
    [self loadArray];
}



-(void) loadArray
{
    CountryInfo *currentCountryOne = [[CountryInfo alloc] init];
    totalArray = [[NSMutableArray alloc] init];

    for (int i=0; i < [countryArray count]; i++)
    {
        currentCountryOne = [countryArray objectAtIndex:i];
        [totalArray addObject:currentCountryOne.countryName];
    }
}


-(void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    if ([searchText length] == 0)
    {
        [displayItems removeAllObjects];
        [displayItems addObjectsFromArray:countryArray];
    }
    else
    {
        [displayItems removeAllObjects];
        displayItems = [[NSMutableArray alloc] init];

        for (NSString *string in totalArray)
        {
            NSRange stringRang = [string rangeOfString:searchText options:NSCaseInsensitiveSearch];
            if (stringRang.location != NSNotFound)
            {
                [displayItems addObject:string];
            }
        }
    }
    [self.countryTableView reloadData];
}



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [displayItems count];
}

// This method is kept the "tableRow height" after "done searching"
- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView
{
    tableView.rowHeight = 100;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    CountryCustomCell *Cell = [self.countryTableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (!Cell)
    {
        Cell = [[CountryCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    currentCountry = [displayItems objectAtIndex:indexPath.row];

    Cell.ContinentLabel.text = currentCountry.continent;
    Cell.CountryNameLabel.text = currentCountry.countryName;
    Cell.CapitalLabel.text = currentCountry.capital;

    imageQueueCountryFlag = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(imageQueueCountryFlag, ^
    {
        UIImage *imageCountryFlag = [UIImage imageWithData:[NSData dataWithContentsOfURL: [NSURL URLWithString:[currentCountry countryFlag]]]];
    dispatch_async(dispatch_get_main_queue(), ^
        {
            Cell.CountryFlagImageView.image = imageCountryFlag;
            [Cell setNeedsLayout];
        });
    });

return Cell;

}

I don't want to use two Array in "numberOfRowsInSection" & "cellForRowAtIndexPath" with flag or some thing like that, to avoid more coding. If any one familiar with it please share that here. A lot of thanks in advanced.


Solution

  • I think you are added objects of CountryInfo in the [countryParser countryArray]. In your loadArray method, you just initializing a blank object currentCountryOne and each time the for loop executes, trying to add a blank object's property into totalArray. Please make changes as below:

    -(void) loadArray
    {
        totalArray = countryArray;
    }
    
    
    -(void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
    {
        if ([searchText length] == 0)
        {
            [displayItems removeAllObjects];
            [displayItems addObjectsFromArray:countryArray];
        }
        else
        {
            [displayItems removeAllObjects];
            displayItems = [[NSMutableArray alloc] init];
    
            for (CountryInfo *country in totalArray)
            {
                NSRange stringRang = [country.countryName rangeOfString:searchText options:NSCaseInsensitiveSearch];
                if (stringRang.location != NSNotFound)
                {
                    [displayItems addObject:country];
                }
            }
        }
        [self.countryTableView reloadData];
    }