在搜索过程中,UITableViewCell详细信息显示按钮按钮太远了

时间:2013-01-30 17:40:14

标签: ios ipad uitableview uisearchbar

UITableViewController UISearchBar作为其tableHeaderView的{​​{1}}。我还初始化了tableViewUISearchDisplayControllerUISearchBarsearchBarUITableViewController。到目前为止一切都很好,一切都很有效。

问题是contentsController的单元格UITableView设置为accessoryType。这是发生的事情:

  1. 首先,一切看起来都应该如此:
    enter image description here
  2. 用户点按UITableViewCellAccessoryDetailDisclosureButton
  3. UISearchBar在主表顶部创建黑色叠加层,并使主表的索引(如UISearchDisplayController)消失。
  4. 假设用户此时隐藏了键盘(通过按下标准键盘上的“隐藏键盘”按钮)
  5. 由于用户尚未在sectionIndexTitlesForTableView中输入任何内容,我们仍然可以看到主表,虽然位于UISearchBar添加的黑色叠加层下方。
  6. 隐藏键盘会暴露主表的 more ,导致主表加载更多单元格。
  7. 现在问题出现了:由于这些单元格在主表的索引被隐藏时被加载,因此公开按钮显示得太偏右(至少与其他单元格相比)。
    enter image description here
  8. 此外,当用户现在取消搜索时,可能不会重新加载这些单元格,导致公开按钮显示在索引下面(现在再次可见)。
    enter image description here
  9. 我对如何解决这个问题感到茫然;我能想到的唯一选择是找到与披露按钮相对应的UIView并手动移动它,但这似乎非常难以理解,只是因为甚至发现了UIView requires a nasty hack。如何以更好的方式解决这个问题的任何建议将非常感激!

    最小可运行示例

    以下是一个最小的例子。只需启动一个新的XCode项目,仅启用ARC,iPad,并使用以下内容替换AppDelegate的内容。请注意,为了最小的例子,我强制主表在UISearchDisplayController重新加载其单元格,否则主表将缓存其单元格并且问题将不会显示(在我的实际应用程序中主表正在重新加载由于其他原因,我不能完全确定原因 - 但当然主表可以随时重新加载单元格。)

    要查看问题,请运行代码,在搜索框中键入内容(您将看到“搜索结果0 .. 5”),然后取消搜索。主表的公开按钮现在显示在索引的下方,而不是旁边。

    以下是代码:

    searchDisplayController:willShowSearchResultsTableView

3 个答案:

答案 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

但是这些产生了相当刺耳的效果,细节披露按钮的位置突然跳跃,所以我推荐如前所述的willBeginSearchwillEndSearch方法。

答案 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];
}