我为这个问题找到了一个更好的解决方案,它似乎在 iOS 6 和 7 上完美运行。虽然它仍然是一个 hack,但它比上面的更清洁和面向未来的 hack。其他解决方案无法始终如一地工作,并阻止某些 UISearchDisplayDelegate 方法触发!此外,我遇到了复杂的嵌入问题,我无法用上述方法解决。其他解决方案的主要问题是它们严重混淆了 UISearchDisplayController 的内部结构。我的解决方案是基于观察 UISearchDisplayContoller 是 UISearchbarDelegate 并且可以通过模拟搜索字段中的按键来触发结果表的自动取消调暗和显示!所以:
- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller
{
if ([controller respondsToSelector: @selector(searchBar:textDidChange:)])
[(id<UISearchBarDelegate>)controller searchBar: controller.searchBar textDidChange: @" "];
}
这段代码通过检查它是否响应 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
此代码通过拦截 textDidChange 委托方法并将 nil 或空字符串更改为空格字符串 @" " 来防止在空搜索栏上发生的正常隐藏/变暗。如果您正在使用第二位代码,那么您可以修改第一位以传递 nil 而不是 @" ",因为第二位将为您进行所需的转换为 @" "。
在我自己的项目中,我需要处理用户输入空格的情况,所以我使用了一个定义的标记,而不是上面的 @" ":
// arbitrary token used internally
#define SEARCH_PRELOAD_CONDITIONAL @"_#preresults#_"
然后通过将其转换回 nil 字符串在内部处理它:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
if ([searchString isEqualToString: SEARCH_PRELOAD_CONDITIONAL])
searchString = nil;
}
享受!:)