• 在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?


  • 相关阅读:
    什么是垃圾回收
    Oracle GoldenGate学习之Goldengate介绍
    JVM虚拟机选项:Xms Xmx PermSize MaxPermSize区别
    查看linux系统版本命令
    Case when 的用法,简单Case函数
    case when then else end
    ORACLE视图添加备注
    修改 tomcat 内存
    Linux 内存机制详解宝典
    oracle正则表达式regexp_like的用法详解
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5322316.html
Copyright © 2020-2023  润新知