UISearchDisplayController - 如何预加载searchResultTableView

eme*_*eer 27 cocoa-touch uisearchbar uisearchdisplaycontroller ios

我想在用户点按搜索栏时,但在输入任何文本之前显示一些默认内容.

我有一个使用settext的解决方案:

- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {

   [searchDisplayController.searchBar setText:@" "];

}
Run Code Online (Sandbox Code Playgroud)

这有效,但它不优雅,搜索栏中的提示文字消失了.

有没有更好的方法将数据预加载到UISearchDisplayController中的SearchResultTableView,而无需在自定义控制器中自己实现整个UISearch功能?

有关所需效果的演示,请查看Safari的搜索框,如果点击它,搜索界面将打开,显示之前的搜索.

Dam*_*sso 9

好的,我有.使用一些数据预加载dataSource并执行以下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];
Run Code Online (Sandbox Code Playgroud)

以下是发生的事情:
在您开始编辑之前,UISearchBar不希望显示searchResultsTableView.如果你触摸tableView(例如reloadData)它将加载并在那里,坐在内存中frame = CGRectZero.你给它一个合适的框架,然后将它添加到searchBar的超级视图,等等.

我通过正确加载tableView 之后显示searchBar的superview和tableView的superview来验证这是正确的- 它们具有相同的superview.所以,我回过头来尽早将tableView添加到superview,确定它会显示出来.对我来说,它显示为暗淡(可能在它之上的另一个视图?alpha设置更低?),但仍然可以点击.我没有进一步,但这肯定会让你的tableView显示没有任何用户交互.

请享用,

达米安


sto*_*onk 8

我发现很多更好的解决这个问题,它似乎在iOS 6和7完美地工作尽管它仍然是一个黑客,它是一个更清洁,面向未来的黑客比上面.其他解决方案不能始终如一地工作,并阻止一些UISearchDisplayDelegate方法被激活!此外,我有复杂的插入问题,我无法通过上述方法解决.其他解决方案的主要问题是它们严重混淆了UISearchDisplayController的内部.我的解决方案基于UISearchDisplayContoller是UISearchbarDelegate的观察结果,并且可以通过在搜索字段中模拟按键来触发结果表的自动调整和显示!所以:

- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller 
{
    if ([controller respondsToSelector: @selector(searchBar:textDidChange:)])
        [(id<UISearchBarDelegate>)controller searchBar: controller.searchBar textDidChange: @" "];
}
Run Code Online (Sandbox Code Playgroud)

这段代码是通过检查它响应UISearchbarDelegate方法来防止崩溃的未来证明,并发送空间@""来欺骗UISearchDisplayController以认为用户输入了一个字母.

现在,如果用户输入内容然后将其删除,则表格将再次变暗.其他解决方案尝试通过在searchDisplayController中执行某些操作来解决此问题:didHideSearchResultsTableView:方法.但这对我来说没有意义,因为当你取消搜索时,它需要真正隐藏你的结果表,你可能需要在这种情况下运行代码.我对这部分的解决方案是子类(注意你可以使用Method Swizzled Category来使它在你的项目中需要时可以在任何地方工作):

// privately declare protocol to suppress compiler warning
@interface UISearchDisplayController (Super) <UISearchBarDelegate>
@end

// subclass to change behavior
@interface GMSearchDisplayController : UISearchDisplayController
@end

@implementation GMSearchDisplayController

- (void) searchBar: (UISearchBar *) searchBar textDidChange: (NSString *) searchString
{
    if (searchString.length == 0)
        searchString = @" ";
    if ([super respondsToSelector: @selector(searchBar:textDidChange:)])
        [super searchBar: searchBar textDidChange: searchString];
}

@end
Run Code Online (Sandbox Code Playgroud)

此代码通过拦截textDidChange委托方法并将nil或空字符串更改为空格字符串@""来防止在空搜索栏上发生的正常隐藏/调暗.如果您正在使用第二位代码,那么您可以修改第一位以传递nil而不是@"",因为第二位将为您执行所需的转换为@"".

在我自己的项目中,我需要处理用户输入空格的情况,因此我使用定义的标记而不是@"".

// arbitrary token used internally
#define SEARCH_PRELOAD_CONDITIONAL @"_#preresults#_"
Run Code Online (Sandbox Code Playgroud)

然后通过将其转换回nil字符串来内部处理它:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    if ([searchString isEqualToString: SEARCH_PRELOAD_CONDITIONAL])
        searchString = nil;
}
Run Code Online (Sandbox Code Playgroud)

请享用!:)


Bou*_*rne -1

为什么不看看 Xcode 中的 TableSearch 项目呢?它或多或少满足了您的需求。它在开头显示一个表格,并在点击搜索字段时将其隐藏。在 Xcode 4 的帮助下查看文档中的 TableSearch 和 API 参考。

另请看一下这个,它几乎可以使用 UISearchBar 和 UITableView 满足您的需要。我更喜欢这种方法。调整一下。

为了进一步满足您的需求,我建议使用两个数据源。一个保存所有内容(这是您一开始显示的内容),另一个保存过滤后的搜索结果。现在继续清空第一个数据源并用第二个数据源的内容填充它以存储并暗淡显示上一个搜索的结果。照此进行。在您的任务的 TableSearch 代码中使用此方法。