Ios UISearchDisplayController-如何预加载SearchResultableView
我想在用户点击搜索栏时,但在输入任何文本之前,显示一些默认内容 我有一个使用settext的解决方案:Ios UISearchDisplayController-如何预加载SearchResultableView,ios,cocoa-touch,uisearchbar,uisearchdisplaycontroller,Ios,Cocoa Touch,Uisearchbar,Uisearchdisplaycontroller,我想在用户点击搜索栏时,但在输入任何文本之前,显示一些默认内容 我有一个使用settext的解决方案: - (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller { [searchDisplayController.searchBar setText:@" "]; } 这是可行的,但并不优雅,搜索栏中的提示文本也消失了 是否有更好的方法将数据预加载到UISearchDi
- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
[searchDisplayController.searchBar setText:@" "];
}
这是可行的,但并不优雅,搜索栏中的提示文本也消失了
是否有更好的方法将数据预加载到UISearchDisplayController中的SearchResultableView,而不必在自定义控制器中自己实现整个UISearch功能
要获得所需效果的演示,请查看Safari的搜索框,如果点击它,搜索界面将打开,显示以前的搜索。为什么不看看Xcode中的TableSearch项目?它或多或少地满足了你的需要。它在开始处显示一个表格,并在点击搜索字段时将其隐藏。在帮助下查看Xcode 4中的文档和API参考中的表搜索 此外,还可以通过UISearchBar和UITableView了解它几乎可以满足您的需要。我更喜欢那种方法。调整它
为了进一步满足您的需求,我建议使用两个数据源。一个保存所有内容(这是您将在最开始显示的内容),另一个保存过滤后的搜索结果。现在继续,清空第一个数据源,并用第二个数据源的内容填充它以存储&dim显示上一次搜索的结果。往这边走。在任务的表搜索代码中使用这种方法。好的,我有了。使用一些数据预加载您的数据源,然后执行以下hack(没有非法操作),您将看到tableView。请注意,可能需要进行一些清理,但这将显示默认数据 在视图控制器的viewDidLoad中,它拥有UISearchBar:
[super viewDidLoad];
[self.searchDisplayController.searchResultsTableView reloadData];
// whatever you named your search bar - mine is property named searchBar
CGRect testFrame = CGRectMake(0, 20, self.searchBar.frame.size.width, 100);
self.searchDisplayController.searchResultsTableView.frame = testFrame;
[self.searchBar.superview addSubview:self.searchDisplayController.searchResultsTableView];
发生的事情如下:在开始编辑之前,UISearchBar不希望显示searchResultsTableView。如果触摸tableView(例如,重新加载数据),它将加载并保存在内存中,frame=CGRectZero。你给它一个合适的框架,然后把它添加到搜索栏的超级视图中,等等 在正确加载tableView之后,我通过显示搜索栏的superview和tableView的superview验证了这一点——它们具有相同的superview。因此,我返回并提前将tableView添加到superview中,果然它出现了。对我来说,它显示为灰色(可能是上面的另一个视图?alpha设置较低?),但仍然可以单击。我没有进一步讨论,但这肯定会让您在没有任何用户交互的情况下显示tableView 享受
Damien这里有一种预填充searchController的方法
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller
{
CGRect testFrame = CGRectMake(0, self.notesSearchBar.frame.size.height, self.notesSearchBar.frame.size.width, self.view.frame.size.height - self.notesSearchBar.frame.size.height);
self.searchDisplayController.searchResultsTableView.frame = testFrame;
[self.notesSearchBar.superview addSubview:self.searchDisplayController.searchResultsTableView];
// [self.view addSubview:self.searchDisplayController.searchResultsTableView];
controller.searchResultsTableView.hidden = NO;
}
-(void) searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView
{
CGRect testFrame = CGRectMake(0, self.notesSearchBar.frame.size.height, self.notesSearchBar.frame.size.width, self.view.frame.size.height - self.notesSearchBar.frame.size.height);
self.searchDisplayController.searchResultsTableView.frame = testFrame;
[self.notesSearchBar.superview addSubview:self.searchDisplayController.searchResultsTableView];
// [self.view addSubview:self.searchDisplayController.searchResultsTableView];
controller.searchResultsTableView.hidden = NO;
}
-(void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
controller.searchResultsTableView.hidden = YES;
}
//一,。用户输入文本后立即保存以前的搜索结果
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
// save searchString
return YES;
}
//二,。在启动时加载上一个搜索字符串
- (void)viewDidLoad
{
// create data source for table view
// searchData may be a NSMutableArray property defined in your interface
self.searchData = // search your master list for searchString
// or create your own list using any search criteria you want
// or you may act depending on user preference
if(!showPreviousSearch)
{
// [searchData removeAllObjects];
}
}
//三,。在询问时提供正确的数据源
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
...
}
NSMutableArray *dataSource = nil;
if (tableView == [[self searchDisplayController] searchResultsTableView])
{
dataSource = self.searchData;
}
else
{
dataSource = self.masterData;
}
...
return cell;
}
//希望这有帮助
谢谢我有办法了。插入这三种方法。必须在tableview中预加载数据才能正常工作。我的代码中有这些代码,所以只要您已经预加载了数据并且正在使用搜索显示控制器,它就必须对您有效
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller
{
CGRect testFrame = CGRectMake(0, self.notesSearchBar.frame.size.height, self.notesSearchBar.frame.size.width, self.view.frame.size.height - self.notesSearchBar.frame.size.height);
self.searchDisplayController.searchResultsTableView.frame = testFrame;
[self.notesSearchBar.superview addSubview:self.searchDisplayController.searchResultsTableView];
// [self.view addSubview:self.searchDisplayController.searchResultsTableView];
controller.searchResultsTableView.hidden = NO;
}
-(void) searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView
{
CGRect testFrame = CGRectMake(0, self.notesSearchBar.frame.size.height, self.notesSearchBar.frame.size.width, self.view.frame.size.height - self.notesSearchBar.frame.size.height);
self.searchDisplayController.searchResultsTableView.frame = testFrame;
[self.notesSearchBar.superview addSubview:self.searchDisplayController.searchResultsTableView];
// [self.view addSubview:self.searchDisplayController.searchResultsTableView];
controller.searchResultsTableView.hidden = NO;
}
-(void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
controller.searchResultsTableView.hidden = YES;
}
iOS 7的工作解决方案:
// When the tableView is hidden, put it back
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
[self.searchDisplayController.searchResultsTableView reloadData];
controller.searchResultsTableView.hidden = NO;
// Also, remove the dark overlay
for (UIView *v in [[controller.searchResultsTableView superview] subviews]) {
// This is somewhat hacky..
if (v.alpha < 1) {
[v setHidden:YES];
}
}
}
-(void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView {
[self.searchDisplayController.searchResultsTableView reloadData];
if (self.searchDisplayController.active == YES) {
tableView.hidden = NO;
}
}
//隐藏tableView时,将其放回
-(void)SearchDisplayControllerIDBeginSearch:(UISearchDisplayController*)控制器{
[self.searchDisplayController.searchResultsTableView重新加载数据];
controller.searchResultsTableView.hidden=否;
//此外,删除黑暗的覆盖
对于(UIView*v在[[controller.searchResultsTableView superview]子视图]中){
//这有点骇人听闻。。
如果(v.alpha<1){
[v:是];
}
}
}
-(void)searchDisplayController:(UISearchDisplayController*)控制器didHideSearchResultsTableView:(UITableView*)tableView{
[self.searchDisplayController.searchResultsTableView重新加载数据];
如果(self.searchDisplayController.active==是){
tableView.hidden=否;
}
}
我找到了一个更好的解决方案,它似乎可以在iOS 6和iOS 7上完美运行。虽然它仍然是一种黑客行为,但它比上面提到的更干净、更能抵御未来的黑客行为。其他解决方案的工作不一致,并阻止某些UISearchDisplayDelegate方法触发!此外,我有复杂的插入问题,我无法解决上述方法。其他解决方案的主要问题是它们严重混淆了UISearchDisplayController的内部。我的解决方案基于这样的观察:UISearchDisplayContoller是一个UISearchbarDelegate,通过模拟搜索字段中的按键可以触发结果表的自动解封和显示!因此:
- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller
{
if ([controller respondsToSelector: @selector(searchBar:textDidChange:)])
[(id<UISearchBarDelegate>)controller searchBar: controller.searchBar textDidChange: @" "];
}
然后通过将其转换回nil字符串对其进行内部处理:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
if ([searchString isEqualToString: SEARCH_PRELOAD_CONDITIONAL])
searchString = nil;
}
享受!:) 这适用于iOS 8:
- (void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView
{
self.searchDisplayController.searchResultsTableView.hidden = NO;
}
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller
{
self.searchDisplayController.searchResultsTableView.hidden = NO;
[self.searchDisplayController.searchResultsTableView.superview.superview bringSubviewToFront:self.searchDisplayController.searchResultsTableView.superview];
CGRect frame = self.searchDisplayController.searchResultsTableView.frame;
self.searchDisplayController.searchResultsTableView.frame = CGRectMake(frame.origin.x, 64, frame.size.width, frame.size.height);
}
但是,我不喜欢这种黑客行为,用我自己的实现(带UITableView的UISearchBar)替换了searchDisplayController。我用UISearchController在iOS 9中测试了以下内容
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller
{
CGRect testFrame = CGRectMake(0, self.notesSearchBar.frame.size.height, self.notesSearchBar.frame.size.width, self.view.frame.size.height - self.notesSearchBar.frame.size.height);
self.searchDisplayController.searchResultsTableView.frame = testFrame;
[self.notesSearchBar.superview addSubview:self.searchDisplayController.searchResultsTableView];
// [self.view addSubview:self.searchDisplayController.searchResultsTableView];
controller.searchResultsTableView.hidden = NO;
}
-(void) searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView
{
CGRect testFrame = CGRectMake(0, self.notesSearchBar.frame.size.height, self.notesSearchBar.frame.size.width, self.view.frame.size.height - self.notesSearchBar.frame.size.height);
self.searchDisplayController.searchResultsTableView.frame = testFrame;
[self.notesSearchBar.superview addSubview:self.searchDisplayController.searchResultsTableView];
// [self.view addSubview:self.searchDisplayController.searchResultsTableView];
controller.searchResultsTableView.hidden = NO;
}
-(void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
controller.searchResultsTableView.hidden = YES;
}
默认情况下,每当UISearchBar中没有文本时,显示的表格将是您的原始表格视图(从这里开始称为originalTableView)。根据演示过程中DIMSBackground的值,该层可能有黑色透明层,也可能没有黑色透明层
一旦用户在UISearchBar中输入任何文本,就会显示新表视图的内容(我将其称为searchTableView)
请注意,在这两种解决方案中,我以类似于苹果在中的方式实现UISearchController;也就是说,有两个独立的UITableViewController负责显示数据
解决方案1:复杂的实施,更流畅的动画
要获得更平滑的动画,请执行以下操作:
实现UISearchControllerDelegate的willPresentSearchController和willDismis
// here tableView refers to originalTableView
extension ViewController: UISearchControllerDelegate {
func willPresentSearchController(searchController: UISearchController) {
data = ["A", "B", "C"]
tableView.reloadData()
}
func willDismissSearchController(searchController: UISearchController) {
data = ["a", "b", "c"]
tableView.reloadData()
}
}
// here tableView refers to searchTableView
extension SearchViewController: UISearchResultsUpdating {
func updateSearchResultsForSearchController(searchController: UISearchController) {
tableView.hidden = false
filterData(text: searchController.searchBar.text!)
tableView.reloadData()
}
}