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

     我在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中输入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,又是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?

查看原文