我UITableViewController
UISearchBar
作为其tableHeaderView
的{{1}}。我还初始化了tableView
,UISearchDisplayController
为UISearchBar
,searchBar
为UITableViewController
。到目前为止一切都很好,一切都很有效。
问题是contentsController
的单元格UITableView
设置为accessoryType
。这是发生的事情:
UITableViewCellAccessoryDetailDisclosureButton
。UISearchBar
在主表顶部创建黑色叠加层,并使主表的索引(如UISearchDisplayController
)消失。sectionIndexTitlesForTableView
中输入任何内容,我们仍然可以看到主表,虽然位于UISearchBar
添加的黑色叠加层下方。我对如何解决这个问题感到茫然;我能想到的唯一选择是找到与披露按钮相对应的UIView并手动移动它,但这似乎非常难以理解,只是因为甚至发现了UIView requires a nasty hack。如何以更好的方式解决这个问题的任何建议将非常感激!
最小可运行示例
以下是一个最小的例子。只需启动一个新的XCode项目,仅启用ARC,iPad,并使用以下内容替换AppDelegate的内容。请注意,为了最小的例子,我强制主表在UISearchDisplayController
重新加载其单元格,否则主表将缓存其单元格并且问题将不会显示(在我的实际应用程序中主表正在重新加载由于其他原因,我不能完全确定原因 - 但当然主表可以随时重新加载单元格。)
要查看问题,请运行代码,在搜索框中键入内容(您将看到“搜索结果0 .. 5”),然后取消搜索。主表的公开按钮现在显示在索引的下方,而不是旁边。
以下是代码:
searchDisplayController:willShowSearchResultsTableView
答案 0 :(得分:1)
如果您希望模仿Apple自己的应用程序在这种情况下的行为方式,那么正确的操作过程将导致详细信息披露按钮全部在启动时向右移动一旦搜索完成,搜索然后再向后移动。
我已经在您的示例中通过以下两个reloadData
方法调用主表视图中的UISearchDisplayDelegate
来实现此目的,我将这些方法添加到您的代码中:
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller
{
[[[self mainTableController] tableView] reloadData];
}
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
[[[self mainTableController] tableView] reloadData];
}
这将强制重新定位您的详细信息披露视图,以考虑表格视图索引的可见性,无论是否处于搜索模式,所有披露指标的位置都保持一致。
<强>更新强>
我玩弄了其他UISearchDisplayDelegate
方法重新加载表格视图,包括:
- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView
- (void)searchDisplayController:(UISearchDisplayController *)controller willUnloadSearchResultsTableView:(UITableView *)tableView
但是这些产生了相当刺耳的效果,细节披露按钮的位置突然跳跃,所以我推荐如前所述的willBeginSearch
和willEndSearch
方法。
答案 1 :(得分:0)
我能想到的最简单,也可能是最干净的方法是告诉你的viewcontroller(或视图)监听键盘事件。然后,当键盘最小化时,您将重新调整搜索栏的第一个响应者并重新加载您的tableview(如果它尚未正确重新加载)。
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//Your code here
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.window];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:self.window];
}
return self;
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name: UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name: UIKeyboardWillHideNotification object:nil];
}
然后添加这两个函数并在其中执行所需的操作。
- (void)keyboardWillHide:(NSNotification *)aNotification
{
//searchbar resignFirstResponder
//Tableview reload (if needed)
}
- (void)keyboardWillShow:(NSNotification *)aNotification
{
//Don't really need this one for your needs
}
由于你在keyboardwillhide函数中辞退了第一个响应者(在键盘开始移动之前),你的tableview单元格应该重新加载,而不必再次重新加载它们。
答案 2 :(得分:0)
问题不仅限于包含节索引标题的表。部分标题标题我遇到了类似的问题。如果你添加
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (tableView != [[self searchDisplay] searchResultsTableView]) {
return [NSString stringWithFormat:@"Section %c", 'A' + section];
} else {
return nil;
}
}
到“最小可运行示例”程序,然后您将看到,一旦重新加载主表视图,节标题标题也会出现在搜索表视图中。 (此处报告了同样的问题:Removing Header Titles from a UITableView in Search Mode。)
我知道的唯一解决方案是,只要搜索显示控制器处于活动状态([self.searchDisplay isActive] == YES
),就避免对主表视图进行所有更新,并仅在卸载搜索表时重新加载主表视图: / p>
- (void)searchDisplayController:(UISearchDisplayController *)controller willUnloadSearchResultsTableView:(UITableView *)tableView {
[[[self mainTableController] tableView] reloadData];
}