9

我想复制 iPhone 联系人应用程序中搜索栏的粘性行为。

正常阶段

当用户向下滚动视图时,搜索栏也会随着视图一起下降:

用户向下滚动视图

如果用户向上滚动,表格会相应地滚动,具有以下两种行为:

(1) 搜索栏保持固定在顶部
(2)后续部分标题适当地停在搜索栏下方

用户向上滚动

当下一个部分标题出现时,前一个标题消失在搜索栏下方:

用户向上滚动

注意:部分索引控件(右侧的 az)也出现在搜索栏的顶部。因此,摆弄contentInset会将部分索引控件随之向下推。

我创建了一个 custom UIViewController,添加了一个UITableView,将其设置contentInset为搜索栏的高度。我创建了一个UIView,将搜索栏添加为其子视图,然后UIViewUITableView. 但是,如上所述,当用户滚动时,部分标题仍停留在 y 位置零处,而不是标题高度。此外,节标题索引控制​​位置也会受到不利影响。

我很感激这个问题的解决方案。

4

2 回答 2

15

把所有的事情都做对已经做了相当多的工作,但我只需要证明可以重新创建这种行为,至少几乎是.
查看我创建的这个 GitHub 项目:https ://github.com/fabiankr/TableViewSearchBar

其实也没那么复杂:
1)直接将搜索栏添加到表格视图中并设置tableView的contentInset
2)在-scrollViewDidScroll:调整搜索栏的框架

不过,您必须注意一些注意事项:
1) 将表格视图滚动到顶部时,部分标题很快就会出现在搜索栏上方。为了解决这个问题,zPosition在滚动到顶部时设置搜索栏
2)您的内容控制器需要是一个子类UIViewController而不是UITableViewController,因为UISearchDisplayController将调光视图添加到控制器的视图中。因为表格视图控制器view是表格视图,所以当表格视图滚动时,调光视图将位于错误的位置。

仅使用公共 API 无法实现的一件事是使表格右侧的部分索引控件与搜索栏重叠。这只是一件小事,即使没有它,其行为也与联系人应用程序中的行为非常相似。

为了实现完全相同的行为,您必须使用私有 API。有一种方法UITableView需要_setPinsTableHeaderView:使用。示例项目包含以下两种实现:1)仅公共 API 和 2)私有 API,以使部分索引控件与搜索栏重叠。
提醒:当您计划将应用程序提交到 App Store 时,您不应该使用私有 API!

于 2013-02-10T14:54:43.560 回答
0

我实现这种行为的方法是将我的浮动单元格从 UITableView 中分离出来,并使其成为 UITableView 的子视图,并在 scrollViewDidScroll 中为浮动单元格设置动画。就这样 UITableView 向下滚动足够远以显示浮动单元格我还在 tableview 中粘贴了一个不可见的单元格,当调用 scrollViewDidScroll 时该单元格被浮动单元格覆盖。

- (void)viewDidLoad {
   // add floating cell to tableview
   FloatingCell *cell = [[FloatingCell alloc] init];
   [self.tableView addSubview:cell];
   self.floatingCell = cell; 
}
// overwrite scrollViewDidScroll
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGRect floatingCellFrame = floatingCell.frame;
    CGFloat floatingCellHeight = floatingCellFrame.size.height;

    // when contentOffset is is more then cellHeight scroll floating cell
    if (scrollView.contentOffset.y > floatingCellHeight) {
       floatingCellFrame.origin.y = -scrollView.contentOffset.y + floatingCellHeight; 

    // when contentOffset is less then cellHeight stick it to the top of UITableView
    else if (scrollView.contentOffset.y < floatingCellHeight)
       floatingCellFrame.origin.y = 0;

   floatingCell.frame = floatingCellFrame;
}

您可能需要在滚动时添加几个极端情况条件,以便浮动单元格不会出现跳跃,但这应该让您开始。祝你好运!

于 2013-02-07T20:50:58.897 回答