我希望在用户点按搜索栏时,但在输入任何文字之前显示一些默认内容。
我有一个使用settext的解决方案:
- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
[searchDisplayController.searchBar setText:@" "];
}
这有效,但它不优雅,搜索栏中的提示文字消失了。
有没有更好的方法将数据预加载到UISearchDisplayController中的SearchResultTableView,而无需在自定义控制器中自己实现整个UISearch功能?
要获得所需效果的演示,请查看Safari的搜索框,如果点击它,搜索界面会打开,显示之前的搜索结果。
答案 0 :(得分: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];
这是发生了什么:
在您开始编辑之前,UISearchBar不希望显示searchResultsTableView。如果你触摸tableView(例如reloadData)它将加载并在那里,坐在内存中frame = CGRectZero。你给它一个合适的框架,然后将它添加到searchBar的超级视图,等等。
我通过在正确加载tableView之后显示searchBar的superview和tableView 的superview来验证这是正确的 - 它们具有相同的superview。所以,我回过头来尽早将tableView添加到superview,确定它会显示出来。对我来说,它显示为暗淡(可能在它之上的另一个视图?alpha设置较低?),但仍然可以点击。我没有进一步,但这肯定会让你的tableView显示没有任何用户交互。
享受,
达明
答案 1 :(得分: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: @" "];
}
此代码通过检查它是否响应UISearchbarDelegate方法来防止崩溃,并发送空间@&#34; &#34;欺骗UISearchDisplayController以使用户输入一个字母。
现在,如果用户键入内容然后将其删除,则表格将再次变暗。其他解决方案尝试通过在searchDisplayController中执行某些操作来解决此问题:didHideSearchResultsTableView:方法。但这对我来说没有意义,因为当你取消搜索时,它需要真正隐藏你的结果表,你可能需要在这种情况下运行代码。我对这部分的解决方案是子类(注意你可以使用一个方法调配类别,使其在项目中需要时可以在任何地方工作):
// 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
此代码通过拦截textDidChange委托方法并将nil或空字符串更改为空格字符串@&#34; &#34;防止在空搜索栏上发生的正常隐藏/调暗。如果你使用第二位代码,那么你可以修改第一位来传递一个nil而不是@&#34; &#34;因为这第二位将进行所需的转换为@&#34; &#34;对你而言。
在我自己的项目中,我需要处理用户输入空格的情况,而不是@&#34; &#34;上面我使用了一个定义的标记:
// arbitrary token used internally
#define SEARCH_PRELOAD_CONDITIONAL @"_#preresults#_"
然后通过将其转换回nil string来内部处理它:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
if ([searchString isEqualToString: SEARCH_PRELOAD_CONDITIONAL])
searchString = nil;
}
享受! :)
答案 2 :(得分:4)
适用于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;
}
}
答案 3 :(得分:1)
我有解决方案。插入这三种方法。您必须预先加载数据的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;
}
答案 4 :(得分:1)
这适用于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);
}
但是,我不喜欢这个hack并用我自己的实现替换了searchDisplayController(UISearchBar和UITableView)。
答案 5 :(得分:1)
我在iOS 9中使用UISearchController测试了以下内容。
默认情况下,只要UISearchBar中没有文本,所显示的表格就是您原来的表格视图(从此处开始称为 originalTableView )。根据{{1}}的值,这可能有也可能没有黑色透明层。
一旦用户将任何文本输入到UISearchBar中,将显示新表视图的内容(我将其称为 searchTableView )。
请注意,在这两个解决方案中,我都是以类似于Apple在this example中这样做的方式实现UISearchController;也就是说,有两个单独的UITableViewController负责显示数据。
解决方案1:复杂的实施,更流畅的动画
更顺畅的动画:
dimsBackgroundDuringPresentation
。reloadData()
。示例:
reloadData()
在这个虚构的示例中,当用户没有关注UISearchBar时,数据显示为// 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()
}
}
,但是当用户点击UISearchBar时,数据显示为a,b,c
。
解决方案2:快速实施,动荡不安
除了在originalTableView和searchTableView中实现搜索控制器的逻辑外,您可以使用此解决方案简单地显示searchTableView,即使它默认是隐藏的。
最有可能的是,您已经在实施UISearchResultsUpdating协议。只需在该方法中调用A,B,C
,就可以获得您所追求的行为;虽然有一个不太出色的动画。
tableView.hidden = false
答案 6 :(得分:-1)
为什么不看看Xcode中的TableSearch项目?它或多或少地满足您的需求。它在开头显示一个表格,并在点击搜索字段时将其缩小。在帮助下检查Xcode 4中的文档和API参考中的TableSearch。
另请查看this它几乎可以满足您对UISearchBar和UITableView的需求。我更喜欢这种方法。调整它。
为了进一步满足您的需求,我建议使用两个数据源。一个保存所有内容(这是您将在一开始显示的内容),另一个保存已过滤的搜索结果。现在继续清空第一个数据源,并用第二个数据源的内容填充它以存储&amp;暗淡显示上一次搜索的结果。继续这样做。在TableSearch代码中使用此方法来完成任务。
答案 7 :(得分:-1)
这是预先填充searchController的方法。
// 1.用户输入文字后立即保存以前的搜索结果
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
// save searchString
return YES;
}
// 2.在启动时加载上一个搜索字符串
- (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];
}
}
// 3.在询问时提供正确的数据源
- (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;
}
//希望这有帮助。
由于