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

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

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


watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGVib2xlZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

    
    
     然后在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?


在storyboard中的静态UITableView中拖入 UISearchBar and Search Display Controller出现的奇怪问题的更多相关文章

  1. 在Storyboard中为UITableView添加Header和Footer

    我在这里所说的Header和Footer并不是sectionHeader和sectionFooter,而是指UITableView的tableHeaderView和tableFooterView,这两 ...

  2. ios用storyboard快速创建静态cell

    在实际开发中经常会遇到下面这样的页面,通常我们用静态cell来做可以快速创建,提高效率 下面讲一下用storyboard创建方法,将一个tableViewController控制器拖入storyboa ...

  3. ios UIScrolloView在storyboard中添加约束

    1.在storyboard中如果有UINavigationbar 或 UITabar 布局的时候需要在控制器中勾选掉 Under Top Bars 和 Under Bottom Bars 这两个选项. ...

  4. WPF Prism MVVM 中 弹出新窗体. 放入用户控件

    原文:WPF Prism MVVM 中 弹出新窗体. 放入用户控件 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_37214567/artic ...

  5. iOS中 xib自定义View在storyboard中的使用

    1,创建UIView 的SubClass 命名为MyView 2, new一个名为MyView的xib p1 3,配置xib的属性 p2 4,为View 添加背景色,添加一个按钮并定制按钮约束,这里我 ...

  6. Django中使用静态资源/文件

    Django中常需要引用js,css,小图像文件,一般我们把这一类文件称为静态文件,放置在static文件夹中,接下来,对Django中配置静态文件进行下傻瓜式的步骤介绍 在工程目录下新建static ...

  7. .NET静态代码织入——肉夹馍(Rougamo)

    肉夹馍是什么 肉夹馍通过静态代码织入方式实现AOP的组件..NET常用的AOP有Castle DynamicProxy.AspectCore等,以上两种AOP组件都是通过运行时生成一个代理类执行AOP ...

  8. .NET静态代码织入——肉夹馍(Rougamo) 发布1.1.0

    肉夹馍(https://github.com/inversionhourglass/Rougamo)通过静态代码织入方式实现AOP的组件,其主要特点是在编译时完成AOP代码织入,相比动态代理可以减少应 ...

  9. .NET静态代码织入——肉夹馍(Rougamo) 发布1.2.0

    肉夹馍(https://github.com/inversionhourglass/Rougamo)通过静态代码织入方式实现AOP的组件,其主要特点是在编译时完成AOP代码织入,相比动态代理可以减少应 ...

随机推荐

  1. C++ 11 笔记 (一) : lambda

    时至今日都是我咎由自取,错就是错,与任何人无关.掉进C++98的各种坑里无法自拔的抖M感,让我选择了华丽丽的无视C++11,导致今日面对开源的代码到各种看不懂的地步,一入C++深似海,我今天愿意承担一 ...

  2. jquery.inputmask.js 输入框input输入内容格式限制插件

    今天使用的就是这几行代码. 利用 jquery.inputmask.js  下载地址(如果打不开的话 请FQ http://plugins.jquery.com/jquery.inputmask/) ...

  3. AppDelegate解析

    当我们创建一个iOS项目,默认会有main.m类,这是一个程序的主入口.main.m方法体如下: #import <UIKit/UIKit.h> #import "AppDele ...

  4. 【C#】动态加载dll程序集

    原文:http://www.cnblogs.com/bomo/archive/2013/03/01/2938165.html 很多时候我们需要用到引用其他程序集,有些程序集是.Net生成的,可以支持反 ...

  5. 修改.htaccess实现子目录绑定示例分享

    <IfModule mod_rewrite.c>RewriteEngine On  RewriteBase /# 把 www.jb51.net改为你要绑定的域名.# 如果是域名:Rewri ...

  6. python中的单下划线和双下划线意义和作用

    Python中并没有真正意义上的“私有”,类的属性的的可见性取决于属性的名字(这里的属性包括了函数).例如,以单下划线开头的属性(例如_spam),应被当成API中非公有的部分(但是注意,它们仍然可以 ...

  7. OneAlert 入门(三)——事件分析

    OneAlert 是国内首个 SaaS 模式的云告警平台,集成国内外主流监控/支撑系统,实现一个平台上集中处理所有 IT 事件,提升 IT 可靠性.有了 OneAlert,你可以更快更合理地为事件划分 ...

  8. WordPress 全方位优化指南(上)

    作为一个全面的 WordPress 性能优化教程,本文旨在帮助读者排查 WordPress 网站的性能问题,同时也提供网站前端优化加速的建议. 如果你曾经遇到过 WordPress 管理界面加载缓慢. ...

  9. File上传

    http://wenku.baidu.com/link?url=bsufrjDQztceWCUw2gqFeYkL1_95t9yIyV1LfHVYL9URAlpWSK_ALO1bAWSlBdnPXYXE ...

  10. NGINX+UWSGI部署生产的DJANGO代码

    并且NGINX不用ROOT帐户哟. 1,编译安装NGINX及UWSGI及DJANGO,不表述 2,将NGINX文件夹更改为普通用户拥有.但执行文件NGINX仍为ROOT,运行如下命令加入特殊权限标志位 ...