我在UITableViewController中有一個UISearchController。每次顯示錶格視圖時,我都希望使用上次搜索的文本填充搜索欄。爲此,我添加了viewDidAppear中的代碼來檢索最後一個搜索字符串並將UISearchController設置爲活動狀態。UITableView中的UISearchController在搜索結果爲空時崩潰
每當我不輸入任何搜索文本,一切工作正常。
當我輸入搜索文本後,搜索第一次正常工作。但是,當我重新打開這個視圖,並用最後一個搜索詞填充UISearchController,並且如果新列表現在返回空結果(這可能是因爲我的tableview中的列表是動態的),那麼應用程序在cellForRowAtIndexPath中崩潰嘗試將行存取到空的搜索結果數組中。
我把NSLogs放在很多地方,發現了一個奇怪的東西。即使UISearchController處於活動狀態,numberOfRowsInSection中的相應條件也會返回FALSE,從而返回原始項目列表中的項目計數,而不是搜索的項目列表(現在爲0)。
它調用numOfRowsInSection,當搜索控制器是積極的,而不是去「如果([_searchController isActive])」該函數的條款,它錯誤變爲「其他」條款,獲取原有名單伯爵(非搜索),它是0,然後調用cellForRowAtIndexPath indexPath.row = 0。奇怪的是,在cellForRowAtIndexPath,它確實去「if(_searchController.active)」子句內。顯然有一些競爭條件或我錯過了一些東西。
我很困惑爲什麼會發生這種情況。將不勝感激任何幫助。
@interface TaalListViewController()
@property (strong, nonatomic) NSArray *m_searchedItemList;
@property NSArray *m_itemList;
@property (retain, nonatomic) UISearchController *searchController;
@end
@implementation TaalListViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
@try {
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// This is a global function declared and returns the items list. This works fine.
_m_itemList = [Globals getItemsList];
// Search controller
_m_searchedItemList = [_m_itemList mutableCopy];
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchBar.delegate = self;
self.searchController.searchResultsUpdater = self;
[self.searchController.searchBar sizeToFit];
self.searchController.dimsBackgroundDuringPresentation = NO;
self.definesPresentationContext = YES;
self.tableView.tableHeaderView = self.searchController.searchBar;
}
@catch (NSException *exception) {
NSLog(@"Caught exception in viewDidLoad");
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
}
}
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Get the last searched text and automatically set it in the search bar
NSString *str = [Globals getLastSearchedText];
if ((str != nil) && (!(str.length == 0)))
{
NSLog(@"Setting seach bar active automatically");
self.searchController.searchBar.text = str;
self.searchController.active = YES;
// [self.searchController.searchBar becomeFirstResponder];
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
@try {
// Return the number of rows in the section.
if ([self.searchController isActive])
{
NSLog(@"Number of searched item rows = %lu", (unsigned long)_m_searchedItemList.count);
return _m_searchedItemList.count;
}
else
{
NSLog(@"Number of regular rows = %lu", (unsigned long)_m_itemList.count);
return _m_itemList.count;
}
}
@catch (NSException *exception) {
NSLog(@"Caught exception in numberOfRowsInSection");
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
@try {
static NSString *CellIdentifier = @"ListTableCell";
ListTableViewCell *cell = (ListTableViewCell *) [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
if (cell == nil)
{
cell = [[ListTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
DisplayListItem *item = nil;
if (self.searchController.active)
{
NSLog(@"Row %ld of search list", (long)indexPath.row);
item = (DisplayListItem *) [_m_searchedItemList objectAtIndex:indexPath.row];
}
else
{
NSLog(@"Row %ld of regular list", (long)indexPath.row);
item = (DisplayListItem *) [_m_itemList objectAtIndex:indexPath.row];
}
// Set the cell here and return
// ...
// Omitted code
// ...
return cell;
}
@catch (NSException *exception) {
NSLog(@"Caught exception in cellForRowAtIndexPath");
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
}
}
#pragma mark - UISearchResultsUpdating
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchString = [self.searchController.searchBar text];
NSLog(@"updateSearchResultsForSearchController called, searchString = %@", searchString);
_m_searchedItemList = [_m_itemList mutableCopy];
if (searchString.length != 0)
{
[self filterContentForSearchText:searchString];
}
[self.tableView reloadData];
}
#pragma mark - UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSLog(@"searchBarSearchButtonClicked called");
[searchBar resignFirstResponder];
}
- (void)filterContentForSearchText:(NSString*)searchText
{
NSLog(@"filterContentForSearchText called");
@try {
NSMutableArray *subPredicates = [NSMutableArray arrayWithCapacity:searchText.count];
for (NSString *searchStr in searchText)
{
[subPredicates addObject:[NSPredicate predicateWithFormat:@"m_name contains[c] %@", searchStr]];
}
NSPredicate *resultPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];
_m_searchedItemList = [_m_itemList filteredArrayUsingPredicate:resultPredicate];
[Globals setLastSearchedText:searchText];
NSLog(@"filterContentForSearchText finished, searched count = %lu", _m_searchedItemList.count);
}
@catch (NSException *exception) {
NSLog(@"Caught exception in filterContentForSearchText");
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
}
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[Globals setLastSearchedText:searchText];
}
@end
這裏是調試器中的NSLogs的輸出。
2016-10-04 22:45:46.364927 AppName[1387:639346] Setting seach bar active automatically
2016-10-04 22:45:46.365378 AppName[1387:639346] updateSearchResultsForSearchController called, searchString = Kay
2016-10-04 22:45:46.365470 AppName[1387:639346] filterContentForSearchText called
2016-10-04 22:45:46.366522 AppName[1387:639346] filterContentForSearchText finished, searched count = 0
2016-10-04 22:45:46.366825 AppName[1387:639346] Number of regular rows = 215
2016-10-04 22:45:46.367319 AppName[1387:639346] updateSearchResultsForSearchController called, searchString = Kay
2016-10-04 22:45:46.367407 AppName[1387:639346] filterContentForSearchText called
2016-10-04 22:45:46.368190 AppName[1387:639346] filterContentForSearchText finished, searched count = 0
2016-10-04 22:45:46.368264 AppName[1387:639346] Number of regular rows = 215
2016-10-04 22:45:46.371081 AppName[1387:639346] Row 0 of search list
2016-10-04 22:45:46.373274 AppName[1387:639346] Caught exception in cellForRowAtIndexPath
2016-10-04 22:45:46.373383 AppName[1387:639346] CRASH: *** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray
2016-10-04 22:45:46.382029 AppName[1387:639346] Stack Trace: (
0 CoreFoundation 0x0000000192d981d8 <redacted> + 148
1 libobjc.A.dylib 0x00000001917d055c objc_exception_throw + 56
2 CoreFoundation 0x0000000192d033dc <redacted> + 0
3 AppName 0x00000001001269bc -[ListViewController tableView:cellForRowAtIndexPath:] + 512
4 UIKit 0x0000000198f243d4 <redacted> + 716
5 UIKit 0x0000000198f24604 <redacted> + 80
6 UIKit 0x0000000198f11bac <redacted> + 2304
7 UIKit 0x0000000198f29668 <redacted> + 116
8 UIKit 0x0000000198cc5b14 <redacted> + 176
9 UIKit 0x0000000198bde54c <redacted> + 1196
10 QuartzCore 0x00000001960a640c <redacted> + 148
11 QuartzCore 0x000000019609b0e8 <redacted> + 292
12 QuartzCore
2016-10-04 22:45:46.382306 AppName[1387:639346] -[_UITableViewReorderingSupport _needsSetup]: unrecognized selector sent to instance 0x170290e00
2016-10-04 22:45:46.382714 AppName[1387:639346] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UITableViewReorderingSupport _needsSetup]: unrecognized selector sent to instance 0x170290e00'
*** First throw call stack:
(0x192d981c0 0x1917d055c 0x192d9f278 0x192d9c278 0x192c9659c 0x198d22c6c 0x198f24440 0x198f24604 0x198f11bac 0x198f29668 0x198cc5b14 0x198bde54c 0x1960a640c 0x19609b0e8 0x19609afa8 0x196017c64 0x19603f0d0 0x19603faf0 0x192d457dc 0x192d4340c 0x192d4389c 0x192c72048 0x1946f5198 0x198c4c628 0x198c47360 0x10015aaa8 0x191c545b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
使用前初始化數組。 –
我已經初始化了數組://這是一個聲明的全局函數並返回項目列表。這工作正常。 _m_itemList = [Globals getItemsList]; //搜索控制器 _m_searchedItemList = [_m_itemList mutableCopy];這段代碼已經在viewDidLoad中初始化了。 – Abhijit
看到這種行爲,當滾動時離開searchmode ...在numberOfRows searchController isActive是YES,當做cellForRowAtIndexPath(因爲滾動),這是否... – Tobias