zoukankan      html  css  js  c++  java
  • 在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?


  • 相关阅读:
    什么是 bean 的自动装配?
    什么是 Spring 的内部 bean?
    什么是 Spring 的 MVC 框架?
    Spring AOP and AspectJ AOP 有什么区别?
    解释 JDBC 抽象和 DAO 模块?
    volatile 类型变量提供什么保证?
    一个 Spring Bean 定义 包含什么?
    什么是 Spring MVC 框架的控制器?
    使用 Spring 访问 Hibernate 的方法有哪些?
    什么是 Callable 和 Future?
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5322316.html
Copyright © 2011-2022 走看看