【问题标题】:filterContentForSearchText and shouldReloadTableForSearchString not called (UITableView & UISearchBar)未调用 filterContentForSearchText 和 shouldReloadTableForSearchString (UITableView & UISearchBar)
【发布时间】:2013-05-21 18:28:40
【问题描述】:

我想实现单词的增量搜索。 我实现如下,但 filterContentForSearchText 和 shouldReloadTableForSearchString 方法没有被调用。为什么?

WordsIndexViewController.h

#import <UIKit/UIKit.h>

@interface WordsIndexViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate>

@end

WordsIndexViewController.m

#import "WordsIndexViewController.h"
#import "WordsShowViewController.h"
#import "Word.h"

@interface WordsIndexViewController ()

@property (strong, nonatomic) UITableView *tableView;

@property (strong, nonatomic) NSArray *words;
@property (strong, nonatomic) NSMutableArray *searchedWords;

@end

@implementation WordsIndexViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    _words = [[app models] objectForKey:@"words"];
    _searchedWords = [NSMutableArray arrayWithArray:@[]];

    UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 480) style:UITableViewStylePlain];
    tableView.delegate = self;
    tableView.dataSource = self;
    _tableView = tableView;

    UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
    searchBar.delegate = self; // needed?
    [searchBar sizeToFit]; // needed?

    UISearchDisplayController *searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
    searchDisplayController.delegate = self;
    searchDisplayController.searchResultsDelegate = self;
    searchDisplayController.searchResultsDataSource = self;
    _tableView.tableHeaderView = searchBar;

    [self.view addSubview:_tableView];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - related to UITableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSLog(@"START numberOfRowsInSection");

    NSArray *words = nil;
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        words = _searchedWords;
    } else {
        words = _words;
    }

    return [words count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"START cellForRowAtIndexPath");

    NSArray *words = nil;
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        words = _searchedWords;
    } else {
        words = _words;
    }

    UITableViewCell *cell = [[UITableViewCell alloc] init];
    Word *word = words[indexPath.row];
    cell.textLabel.text = word.spelling;
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSArray *words = nil;
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        words = _searchedWords;
    } else {
        words = _words;
    }

    WordsShowViewController *controller = [[WordsShowViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    controller.word = (Word *)words[indexPath.row];
    [self.navigationController pushViewController:controller animated:YES];
}

#pragma mark - related to Search Bar
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
    NSLog(@"Query: %@", searchString); // NOT CALLED...

    [self filterContentForSearchText:searchString
        scope:[
            [self.searchDisplayController.searchBar scopeButtonTitles]
            objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]
        ]
    ];

    return YES;
}
- (void)filterContentForSearchText:(NSString*)searchString scope:(NSString*)scope {
    NSLog(@"START filterContentForSearchText"); // NOT CALLED...

    [_searchedWords removeAllObjects];

    for(Word *word in _words) {
        NSRange range = [word.spelling rangeOfString:searchString options:NSCaseInsensitiveSearch];
        if(range.length > 0) {
            [_searchedWords addObject:word];
        }
    }
}

@end

Word.h

#import <Foundation/Foundation.h>

@interface Word : NSObject

@property (strong, nonatomic) NSString *identifier;
@property (strong, nonatomic) NSString *spelling;

- (id)initWith:(NSString *)spelling;

@end

Word.m

#import "Word.h"

@implementation Word

- (id)initWith:(NSString *)spelling {
    self = [super init];
    if (!self) {
        return nil;
    }

    CFUUIDRef uuid = CFUUIDCreate(NULL);
    _identifier = (NSString *)CFBridgingRelease(CFUUIDCreateString(NULL, uuid));
    CFRelease(uuid);

    _spelling = spelling;

    return self;
}

@end

问候,

【问题讨论】:

    标签: objective-c uitableview uisearchbar uisearchdisplaycontroller uisearchbardelegate


    【解决方案1】:

    最后,我自己解决了这个问题。

    为了解决这个问题,我在 textDidChange 中调用了 shouldReloadTableForSearchString 然后增量搜索起作用了。差异如下:

    WordsIndexViewController.m

    @@ -16,6 +16,7 @@
          @property (strong, nonatomic) NSArray *words;
     @property (strong, nonatomic) NSMutableArray *searchedWords;
    +@property (strong, nonatomic) UISearchDisplayController *displayController;
    
     @end
    
    @@ -52,6 +53,7 @@
         searchDisplayController.searchResultsDelegate = self;
         searchDisplayController.searchResultsDataSource = self;
         _tableView.tableHeaderView = searchBar;
    +    _displayController = searchDisplayController;
    
         [self.view addSubview:_tableView];
     }
    @@ -132,5 +134,9 @@
             }
         }
     }
    +- (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *) searchText {
    +    [self searchDisplayController:_displayController shouldReloadTableForSearchString:searchText];
    +}
    
     @end
    

    谢谢,

    【讨论】:

      【解决方案2】:

      确保在头文件中为 UISearchDisplayController 创建 iVar。

      如果您使用以下方法创建 UISearchDisplayController:

      UISearchDisplayController* searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchField contentsController:self];

      它将由 ARC 释放,它不会调用任何委托方法,当您调用 self.searchDisplayController(UIViewController 的属性)时,它将是 nil

      所以,解决方法是: 在您的标头 (.h) 文件中:

      @interface MenuViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UISearchDisplayDelegate> {
              UISearchDisplayController* searchDisplayController;
              UISearchBar *searchField;
              UITableView* tableView;
              NSArray* searchResults;
      }
      

      在实现(.m)文件中:

      searchField = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 49)];
      searchField.delegate = self;
      
      searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchField contentsController:self];
      searchDisplayController.delegate = self;
      searchDisplayController.searchResultsDataSource = self;
      searchDisplayController.searchResultsDelegate = self;
      
      tableView.tableHeaderView = searchField;
      tableView.contentOffset = CGPointMake(0, searchField.frame.size.height);
      

      当这样实现时,您可以在其余代码中同时调用 self.searchDisplayControllersearchDisplayController

      【讨论】:

        猜你喜欢
        • 2019-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多