使用beginUpdates / endUpdates时,UISearchBar从tableHeaderView中消失

时间:2016-07-27 11:14:30

标签: ios uitableview cocoa-touch uisearchbar uisearchcontroller

我有一个带有UISearchController的表格视图控制器,可将UISearchBar设置为tableView.tableHeaderView。更新搜索结果时,我使用beginUpdatesendUpdates及相关方法更新表格视图的数据。

这使搜索栏消失; tableHeaderView设置为与搜索栏大小相同的空的通用UIView。如果我只使用reloadData而不是整个beginUpdates / endUpdates程序,那么一切都很好。

表视图控制器嵌入在常规视图控制器中;没有涉及导航控制器。这是重现问题所需的表视图控制器的整个实现:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
    self.searchController.searchResultsUpdater = self;
    self.searchController.dimsBackgroundDuringPresentation = NO;

    self.tableView.tableHeaderView = self.searchController.searchBar;
}

- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
    [self.tableView beginUpdates];
    [self.tableView endUpdates];
}

为什么这会导致搜索栏被替换为空白视图,以及如何避免?

2 个答案:

答案 0 :(得分:0)

首次点击UISearchController's searchBar时,searchBar需要大约0.5秒来制作动画。但是委托方法立即调用了self.tableView.endUpdates(),动画被中断了   搜索栏停留在动画的中间,你无法看到它的UI:
loosely coupled object factory

解决方法是检查searchBar是否在动画中,并在它进入时延迟self.tableView.endUpdates()

func updateSearchResultsForSearchController(searchController: UISearchController){
    self.tableView.beginUpdates()
    //Do some updates

    if !searchController.searchBar.showsCancelButton{
        self.tableView.performSelector(#selector(UITableView.endUpdates), withObject: nil, afterDelay: 1)

    }else{
        self.tableView.endUpdates()
    }
}

答案 1 :(得分:0)

关于beginUpdates, endUpdates and reloadData

的修订很少

beginUpdates::开始一系列方法调用,插入,删除或选择表视图的行和部分。 如果要同时为后续插入,删除和选择操作(例如,cellForRowAtIndexPath:和indexPathsForVisibleRows)设置动画,请调用此方法。您还可以使用此方法,然后使用endUpdates方法为行高度的更改设置动画,而无需重新加载单元格。这组方法必须以调用endUpdates结束。这些方法对可以嵌套。如果未在此块内进行插入,删除和选择调用,则行计数等表属性可能会变为无效。你不应该在组内调用reloadData;如果您在组中调用此方法,则必须自己执行任何动画。

endUpdates:结束一系列方法调用,用于插入,删除,选择或重新加载表视图的行和部分。 您可以调用此方法来括起一系列以beginUpdates开头的方法调用,这些方法调用包括插入,删除,选择和重新加载表视图的行和部分的操作。当您调用endUpdates时,UITableView会同时为操作设置动画。可以嵌套beginUpdates和endUpdates的调用。如果未在此块内进行插入,删除和选择调用,则行计数等表属性可能会变为无效。

reloadData:重新加载表格视图的行和部分。 调用此方法可重新加载用于构造表的所有数据,包括单元格,节页眉和页脚,索引数组等。为了提高效率,表视图仅重新显示可见的行。如果表因重新加载而缩小,它会调整偏移量。表视图的委托或数据源在希望表视图完全重新加载其数据时调用此方法。它不应该在插入或删除行的方法中调用,尤其是在通过调用beginUpdates和endUpdates实现的动画块中。

现在,在搜索的情况下,我们不知道哪些行会影响每次搜索结果数据会有所不同,我相信一个人不应该使用

[self.tableView beginUpdates];
[self.tableView endUpdates];

在您对tableview执行insert, update or delete操作时使用,并且您知道其indexPath

更好地使用[self.tableView reloadData];,因为它只会更新tableview中的可见行或部分。另请参阅Apple的Table Search with UISearchController示例代码,还建议使用reloadData

进行各自的更改,你很高兴。

快乐编码:)