在storyboard中的静态UITableView中拖入 UISearchBar and Search Display Controller出现的奇怪问题

     近期学习过程中想模拟一下新浪微博“发现”界面。

     我在storyboard中拖入一个UITableViewController,设置这个UITableViewController的TableView为Static Cells,然后加入了两个Section,每一个Section两行Cell。

     接下来往这个TableView中拖入了一个UISearchBar and Search Display Controller,storyboard中的结构例如以下图:



    
    
     然后在UITableViewController相应的WBDiscoverTableViewController.m中实现相关的协议方法。代码例如以下:

#import "WBDiscoverTableViewController.h"

@interface WBDiscoverTableViewController ()
@property (weak, nonatomic) IBOutlet UISearchBar *mySearchbar;
@property (nonatomic, strong) NSArray *results;
@property (weak, nonatomic) IBOutlet UITableViewCell *hotTopicsCell1;
@property (weak, nonatomic) IBOutlet UITableViewCell *hotTopicsCell2;
@property (weak, nonatomic) IBOutlet UITableViewCell *nearbyPeopleCell;
@property (weak, nonatomic) IBOutlet UITableViewCell *nearbyWeiboCell;
@end

@implementation WBDiscoverTableViewController

- (
void)viewDidLoad {
    [super viewDidLoad];

    static NSString *cellID = @"resultCell";
    [
self.searchDisplayController.searchResultsTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellID];
}

- (
void)viewWillAppear:(BOOL)animated {

}

- (void)searchWithString {
   
switch (self.mySearchbar.selectedScopeButtonIndex) {
       
case 0:
           
//搜用户
           
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"accessToken"]) {
                [[
WBWeiboAPI shareWeiboApi] searchSuggestionsUsersWithString:self.mySearchbar.text AndCount:20 CompletionCallBack:^(id obj) {
                   
self.results = obj;
                   
dispatch_async(dispatch_get_main_queue(), ^{
                       
NSLog(@"self.results.count :%ld", self.results.count);
                        [
self.searchDisplayController.searchResultsTableView reloadData];
                    });
                   
                }];
            }
           
break;
       
case 1:
           
//搜学校
           
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"accessToken"]) {
                [[
WBWeiboAPI shareWeiboApi] searchSuggestionsSchoolsWithString:self.mySearchbar.text AndCount:20 AndType:0 CompletionCallBack:^(id obj) {
                   
self.results = obj;
                   
dispatch_async(dispatch_get_main_queue(), ^{
                       
NSLog(@"self.results.count :%ld", self.results.count);
                        [
self.searchDisplayController.searchResultsTableView reloadData];
                    });
                }];
            }
           
break;
       
case 2:
           
//搜公司
           
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"accessToken"]) {
                [[
WBWeiboAPI shareWeiboApi] searchSuggestionsCompaniesWithString:self.mySearchbar.text AndCount:20 CompletionCallBack:^(id obj) {
                   
self.results = obj;
                   
dispatch_async(dispatch_get_main_queue(), ^{
                       
NSLog(@"self.results.count :%ld", self.results.count);
                        [
self.searchDisplayController.searchResultsTableView reloadData];
                    });
                }];
            }
           
break;
       
default:
           
break;
    }
}

#pragma mark UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [
self searchWithString];
   
}

#pragma mark UISearchDisplayDelegate

- (
void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
   
NSLog(@"WillBeginSearch....");
}

- (
void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
   
NSLog(@"DidBeginSearch....");
}

- (
void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
   
NSLog(@"WillEndSearch....");
}

- (
void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller {
   
NSLog(@"DidEndSearch....");
}

- (
BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
    [
self searchWithString];
   
return NO;
}

- (
BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
    [
self searchWithString];
   
return NO;
}

#pragma mark - Table view data source
//因为这个控制器既是原来的WBDiscoverTableViewController。又是UISearchDisplayControllersearchContentsController
//WBDiscoverTableViewControllertableViewsearchResultsTableViewdelegat都指向这个对象(self)。
//所以须要在回调中差别究竟是哪个tableView

- (
NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
   
if (tableView == self.tableView) {
       
return 2;
    }
else if (tableView == self.searchDisplayController.searchResultsTableView){
       
return 1;
    }
else
       
return 0;
}

- (
NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
   
if (tableView == self.tableView) {
       
return 2;
       
    }
else if (tableView == self.searchDisplayController.searchResultsTableView) {
       
return self.results.count;

    }
else
       
return 0;
}

- (
UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

   
if (tableView == self.tableView) {
       
       
if (indexPath.section == 0 && indexPath.row == 0) {
           
return self.hotTopicsCell1;
        }
else if (indexPath.section == 0 && indexPath.row == 1) {
           
return self.hotTopicsCell2;
        }
else if (indexPath.section == 1 && indexPath.row == 0) {
           
return self.nearbyPeopleCell;
        }
else {
           
return self.nearbyWeiboCell;
        }
       
    }
else if (tableView == self.searchDisplayController.searchResultsTableView) {

       
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"resultCell"];
       
id result = self.results[indexPath.row];
       
if ([result isMemberOfClass:[WBSearchSuggestionsOfUsers class]]) {
           
WBSearchSuggestionsOfUsers * suggestion = result;
            cell.
textLabel.text = suggestion.nickName;
            cell.
detailTextLabel.text = suggestion.followersCount;
        }
else if ([result isMemberOfClass:[WBSearchSuggestionsOfSchools class]]) {
           
WBSearchSuggestionsOfSchools *suggestion = result;
            cell.
textLabel.text = suggestion.schoolName;
            cell.
detailTextLabel.text = suggestion.location;
        }
else {
           
WBSearchSuggestionsOfCompanies *suggestion = result;
            cell.
textLabel.text = suggestion.suggestion;
        }
       
return cell;
    }
else
       
return nil;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
       
return 10;
}

- (
void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
   
UIViewController *vc = [[UIViewController alloc]init];
    vc.
view.backgroundColor = [UIColor whiteColor];
    [
self.navigationController pushViewController:vc animated:YES];
   
    }

@end

     当我在UISearchBar中输入keyword进行搜索。假设返回结果的数量(self.results.count)大于2的时候,程序就会崩溃,错误原因:reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1]

     看起来是数组訪问越界了,也就是说数组中仅仅有两个对象,可是却訪问了index为2的对象。于是程序就崩溃了。

检查了代码,并没有什么异常,最后想到是不是静态TableView导致的问题呢?

     于是决定将TableView改动为动态的,并改动WBDiscoverTableViewController.m中的代码:

#import "WBDiscoverTableViewController.h"

@interface WBDiscoverTableViewController ()
@property (weak, nonatomic) IBOutlet UISearchBar *mySearchbar;
@property (nonatomic, strong) NSArray *results;
@end

@implementation WBDiscoverTableViewController

- (
void)viewDidLoad {
    [
super viewDidLoad];
     
    [self.searchDisplayController.searchResultsTableView registerNib:[UINib nibWithNibName:@"WBsearchSuggestionCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"WBsearchSuggestionCell"];
   
    [
self.tableView registerNib:[UINib nibWithNibName:@"hotTopicsCell1" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"hotTopicsCell1"];
   
    [
self.tableView registerNib:[UINib nibWithNibName:@"hotTopicsCell2" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"hotTopicsCell2"];
   
    [
self.tableView registerNib:[UINib nibWithNibName:@"nearbyPeopleCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"nearbyPeopleCell"];
   
    [
self.tableView registerNib:[UINib nibWithNibName:@"nearbyWeiboCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"nearbyWeiboCell"];
   
}


- (void)searchWithString {
   
switch (self.mySearchbar.selectedScopeButtonIndex) {
       
case 0:
           
//搜用户
           
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"accessToken"]) {
                [[
WBWeiboAPI shareWeiboApi] searchSuggestionsUsersWithString:self.mySearchbar.text AndCount:20 CompletionCallBack:^(id obj) {
                   
self.results = obj;
                   
dispatch_async(dispatch_get_main_queue(), ^{
                       
NSLog(@"self.results.count :%ld", self.results.count);
                        [
self.searchDisplayController.searchResultsTableView reloadData];
                    });
                   
                }];
            }
           
break;
       
case 1:
           
//搜学校
           
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"accessToken"]) {
                [[
WBWeiboAPI shareWeiboApi] searchSuggestionsSchoolsWithString:self.mySearchbar.text AndCount:20 AndType:0 CompletionCallBack:^(id obj) {
                   
self.results = obj;
                   
dispatch_async(dispatch_get_main_queue(), ^{
                       
NSLog(@"self.results.count :%ld", self.results.count);
                        [
self.searchDisplayController.searchResultsTableView reloadData];
                    });
                }];
            }
           
break;
       
case 2:
           
//搜公司
           
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"accessToken"]) {
                [[
WBWeiboAPI shareWeiboApi] searchSuggestionsCompaniesWithString:self.mySearchbar.text AndCount:20 CompletionCallBack:^(id obj) {
                   
self.results = obj;
                   
dispatch_async(dispatch_get_main_queue(), ^{
                       
NSLog(@"self.results.count :%ld", self.results.count);
                        [
self.searchDisplayController.searchResultsTableView reloadData];
                    });
                }];
            }
           
break;
       
default:
           
break;
    }
}

#pragma mark UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [
self searchWithString];
   
}


#pragma mark UISearchDisplayDelegate

- (
void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
   
NSLog(@"WillBeginSearch....");
}

- (
void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
   
NSLog(@"DidBeginSearch....");
}

- (
void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
   
NSLog(@"WillEndSearch....");
}

- (
void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller {
   
NSLog(@"DidEndSearch....");
}

- (
BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
    [
self searchWithString];
   
return NO;
}

- (
BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
    [
self searchWithString];
   
return NO;
}

#pragma mark - Table view data source
//因为这个控制器既是原来的WBDiscoverTableViewController,又是UISearchDisplayControllersearchContentsController


//WBDiscoverTableViewControllertableViewsearchResultsTableViewdelegat都指向这个对象(self)。
//所以须要在回调中差别究竟是哪个tableView

- (
NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
   
if (tableView == self.tableView) {
       
return 2;
    }
else if (tableView == self.searchDisplayController.searchResultsTableView){
       
return 1;
    }
else
       
return 0;
}

- (
NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
   
if (tableView == self.tableView) {
       
return 2;
       
    }
else if (tableView == self.searchDisplayController.searchResultsTableView) {
       
return self.results.count;

    }
else
       
return 0;
}

- (
UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

   
if (tableView == self.tableView) {
   
       
if (indexPath.section == 0 && indexPath.row == 0) {
           
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"hotTopicsCell1" forIndexPath:indexPath];
           
return cell;
        }
else if (indexPath.section == 0 && indexPath.row == 1) {
           
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"hotTopicsCell2" forIndexPath:indexPath];
           
return cell;
        }
else if (indexPath.section == 1 && indexPath.row == 0) {
           
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"nearbyPeopleCell" forIndexPath:indexPath];
           
return cell;
        }
else {
           
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"nearbyWeiboCell" forIndexPath:indexPath];
           
return cell;
        }
       
    }
else if (tableView == self.searchDisplayController.searchResultsTableView) {

       
WBsearchSuggestionCell *cell = [tableView dequeueReusableCellWithIdentifier:@"WBsearchSuggestionCell" forIndexPath:indexPath];
       
id result = self.results[indexPath.row];
       
       
if ([result isMemberOfClass:[WBSearchSuggestionsOfUsers class]]) {
           
WBSearchSuggestionsOfUsers * suggestion = result;
            cell.
suggestion.text = suggestion.nickName;
        }
else if ([result isMemberOfClass:[WBSearchSuggestionsOfSchools class]]) {
           
WBSearchSuggestionsOfSchools *suggestion = result;
            cell.
suggestion.text = suggestion.schoolName;
           
        }
else {
           
WBSearchSuggestionsOfCompanies *suggestion = result;
            cell.
suggestion.text = suggestion.suggestion;
        }
       
return cell;
    }
else
       
return nil;
}


- (
CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
       
return 10;
}

- (
void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView
deselectRowAtIndexPath:indexPath animated:YES];

   
UIViewController *vc = [[UIViewController alloc]init];
    vc.
view.backgroundColor = [UIColor whiteColor];
    [
self.navigationController pushViewController:vc animated:YES];
   

}

@end

     測试,问题攻克了!

     可是仍然心存疑问。为什么静态TableView会影响UISearchBar and Search Display Controller中 searchResultsTableView的cell?


posted @ 2016-03-26 10:33  zfyouxi  阅读(476)  评论(0编辑  收藏  举报