不调用filterContentForSearchText和shouldReloadTableForSearchString(UITableView& UISearchBar) [英] filterContentForSearchText and shouldReloadTableForSearchString not called (UITableView & UISearchBar)
问题描述
我想实现单词的增量搜索. 我实现如下,但是未调用filterContentForSearchText和shouldReloadTableForSearchString方法.为什么?
I'd like to implement an incremental search of words. I implemented like below, but filterContentForSearchText and shouldReloadTableForSearchString methods are not called. Why?
WordsIndexViewController.h
WordsIndexViewController.h
#import <UIKit/UIKit.h>
@interface WordsIndexViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate>
@end
WordsIndexViewController.m
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
此致
推荐答案
确保在头文件中为UISearchDisplayController创建一个iVar.
Make sure you create an iVar for the UISearchDisplayController in your header file.
如果您使用以下方法创建UISearchDisplayController:
If you create an UISearchDisplayController using:
UISearchDisplayController* searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchField contentsController:self];
它将由ARC发布,它不会调用任何委托方法,当您调用self.searchDisplayController
(UIViewController的属性)时,它将是nil
.
it will get released by ARC, it will not call any delegate methods and when you'll call self.searchDisplayController
(the UIViewController's property) it will be nil
.
因此,解决方法是: 在您的标头(.h)文件中:
So, the fix is: In your header (.h) file:
@interface MenuViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UISearchDisplayDelegate> {
UISearchDisplayController* searchDisplayController;
UISearchBar *searchField;
UITableView* tableView;
NSArray* searchResults;
}
以及在实施(.m)文件中:
and in the implementation (.m) file:
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.searchDisplayController
和searchDisplayController
.
When implemented like that, you can call both self.searchDisplayController
and searchDisplayController
in the rest of your code.
这篇关于不调用filterContentForSearchText和shouldReloadTableForSearchString(UITableView& UISearchBar)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!