博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在storyboard中的静态UITableView中拖入 UISearchBar and Search Display Controller出现的奇怪问题...
阅读量:6904 次
发布时间:2019-06-27

本文共 13117 字,大约阅读时间需要 43 分钟。

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

     我在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?
你可能感兴趣的文章
windows phone Image checkbox
查看>>
[pycharm]远程调试服务器项目
查看>>
7 Java NIO Selector-翻译
查看>>
All Users in SharePoint Site Custom Webpart
查看>>
pip下载源更换为豆瓣源
查看>>
React Render props
查看>>
自动类型转换
查看>>
C# winfrom 当前程序内存读取和控制
查看>>
电话号码分身
查看>>
计算机专业术语
查看>>
Leetcode-探索 | 移动零
查看>>
DBI 数据库模块剖析:Perl DBI 数据库通讯模块规范,工作原理和实例
查看>>
Tesseract+opencv+VS+win实现OCR
查看>>
android在activity中锁屏解锁后重走OnCreate的问题的解决办法
查看>>
[学习笔记]博弈论
查看>>
python os sys模块(二)
查看>>
一次linux启动故障记录
查看>>
linux 3.10内核 xfs的一次io异常导致的hung crash
查看>>
Castle ActiveRecord学习笔记(转)
查看>>
springboot+mybatis环境的坑和sql语句简化技巧
查看>>