iPhone TableView Search XML

2019-04-01 23:48发布

I have a question about adding XML to the searchbar in a tableview. I can get all the external XML file to load in the tableview, but when I hit the searchbar up top, and hit a letter, it crashes.

I think it's something really simple that I'm doing wrong. In my RootViewController, there's a function called searchTableView. I feel like that's where it's not picking up the search items. I think it's somewhere around the objectForKey:@"title". When I debug, I get this error message also: "NSCFArray objectForKey unrecognized selector". Here's my searchTableView function:

- (void) searchTableView {

    NSString *searchText = searchBar.text;
    NSMutableArray *searchArray = [[NSMutableArray alloc] init];

    for (NSDictionary *dictionary in listOfItems)
    {
        NSArray *array = [dictionary objectForKey:@"title"];
        [searchArray addObjectsFromArray:array];
    }

    for (NSString *sTemp in searchArray)
    {
        NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];

        if (titleResultsRange.length > 0)
            [copyListOfItems addObject:sTemp];
    }

    [searchArray release];
    searchArray = nil;
}

1条回答
欢心
2楼-- · 2019-04-02 00:06

Ok figured it out. For some reason this was really hard to find documentation how to do this.

Here's my RootViewController.m below.

My pList is configured as:

  • Root (Array)
  • Item0 (Dictionary)
  • Name (String)
  • Item1 (Dictionary)
  • Name (String)..

Here's my code, hopefully this helps anyone else looking for help on this:

@implementation RootViewController
@synthesize listOfItems, copyListOfItems;

- (void)viewDidLoad {
    [super viewDidLoad];

    //Initialize the array.
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"plistArray" ofType:@"plist"];  
    NSMutableArray* tmpArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
    self.listOfItems = tmpArray;
    [tmpArray release];

    //Initialize the copy array.
    copyListOfItems = [[NSMutableArray alloc] init];

    //Set the title
    self.navigationItem.title = @"Search";

    //Add the search bar
    self.tableView.tableHeaderView = searchBar;
    searchBar.autocorrectionType = UITextAutocorrectionTypeNo;

    searching = NO;
    letUserSelectRow = YES;
}



- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}

#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    if (searching)
        return 1;
    else
        return 1;
}

// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    if (searching)
        return [copyListOfItems count];
    else {

        //Number of rows it should expect should be based on the section
        return [listOfItems count];
    }
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    //Get the selected country

    NSString *selectedCountry = nil;

    if(searching)
        selectedCountry = [copyListOfItems objectAtIndex:indexPath.row];
    else {

        // Navigation logic may go here. Create and push another view controller.

    }

    NSDictionary *dictionary = [self.listOfItems objectAtIndex:indexPath.row];
    FoodDetail *dvController = [[FoodDetail alloc] initWithNibName:@"FoodDetail" bundle:nil andDictionary: dictionary];

    // Pass the selected object to the new view controller.
    [self.navigationController pushViewController:dvController animated:YES];
    [dvController release];

}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }

    // Set up the cell...

    if(searching) 
        cell.textLabel.text = [copyListOfItems objectAtIndex:indexPath.row];
    else {

        cell.textLabel.text = [[self.listOfItems objectAtIndex:indexPath.row] 
                               objectForKey:@"Name"];
    }

    return cell;
}



- (NSIndexPath *)tableView :(UITableView *)theTableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    if(letUserSelectRow)
        return indexPath;
    else
        return nil;
}





#pragma mark -
#pragma mark Search Bar 

- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {

    //This method is called again when the user clicks back from the detail view.
    //So the overlay is displayed on the results, which is something we do not want to happen.
    if(searching)
        return;

    //Add the overlay view.
    if(ovController == nil)
        ovController = [[OverlayViewController alloc] initWithNibName:@"OverlayView" bundle:[NSBundle mainBundle]];

    CGFloat yaxis = self.navigationController.navigationBar.frame.size.height;
    CGFloat width = self.view.frame.size.width;
    CGFloat height = self.view.frame.size.height;

    //Parameters x = origion on x-axis, y = origon on y-axis.
    CGRect frame = CGRectMake(0, yaxis, width, height);
    ovController.view.frame = frame;    
    ovController.view.backgroundColor = [UIColor grayColor];
    ovController.view.alpha = 0.5;

    ovController.rvController = self;

    [self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];

    searching = YES;
    letUserSelectRow = NO;
    self.tableView.scrollEnabled = NO;

    //Add the done button.
    self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] 
                                               initWithBarButtonSystemItem:UIBarButtonSystemItemDone 
                                               target:self action:@selector(doneSearching_Clicked:)] autorelease];

}

- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {

    //Remove all objects first.
    [copyListOfItems removeAllObjects];

    if([searchText length] > 0) {

        [ovController.view removeFromSuperview];
        searching = YES;
        letUserSelectRow = YES;
        self.tableView.scrollEnabled = YES;
        [self searchTableView];
    }
    else {

        [self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];

        searching = NO;
        letUserSelectRow = NO;
        self.tableView.scrollEnabled = NO;
    }

    [self.tableView reloadData];
}

- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar {

    [self searchTableView];
}

- (void) searchTableView {

    NSString *searchText = searchBar.text;
    NSMutableArray *searchArray = [[NSMutableArray alloc] init];

    for (NSDictionary *dictionary in listOfItems)
    {
        NSString *text1 = [dictionary objectForKey:@"Name"];
        [searchArray addObject:text1];
    }   
    NSLog(@"%s: searchArray=%@", __func__, searchArray);

    for (NSString *sTemp in searchArray)
    {
        NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];

        if (titleResultsRange.length > 0)
            [copyListOfItems addObject:sTemp];
    }

    [searchArray release];
    searchArray = nil;
}

- (void) doneSearching_Clicked:(id)sender {

    searchBar.text = @"";
    [searchBar resignFirstResponder];

    letUserSelectRow = YES;
    searching = NO;
    self.navigationItem.rightBarButtonItem = nil;
    self.tableView.scrollEnabled = YES;

    [ovController.view removeFromSuperview];
    [ovController release];
    ovController = nil;

    [self.tableView reloadData];
}


- (void)dealloc {

    [ovController release];
    [copyListOfItems release];
    [searchBar release];
    [listOfItems release];
    [super dealloc];
}


@end
查看更多
登录 后发表回答