最近学习过程中想模拟一下新浪微博“发现”界面。
我在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,又是UISearchDisplayController的searchContentsController。
//WBDiscoverTableViewController的tableView和searchResultsTableView的delegat都指向这个对象(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中输入关键字进行搜索,如果返回结果的数量(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,又是UISearchDisplayController的searchContentsController。
//WBDiscoverTableViewController的tableView和searchResultsTableView的delegat都指向这个对象(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?