14

我希望能够在用户滚动时修复 UITableView 中某些行的位置。

具体来说,我有一个表格,其中某些行是随后行的“标题”,我希望标题在用户向上滚动时保持在屏幕顶部。当用户滚动到下一个标题行将取代它的位置时,它就会移开。

一个类似的例子是 Any.DO 应用程序。“今天”、“明天”和“以后”表格行在屏幕上始终可见。

有人对如何实施有任何建议吗?

我目前正在考虑遵循 TableDidScroll 委托并将我自己的单元格放置在表格视图前面的适当位置。问题是,在其他时候,我真的希望这些单元格成为真正的表格单元格,以便它们可以例如由用户重新排序。

谢谢,

蒂姆

4

3 回答 3

13

我一直在玩这个,我想出了一个简单的解决方案。

首先,我们向控制器添加一个 UITableViewCell 属性。这应该被初始化,使其看起来与我们将用于创建虚假节标题的行单元格完全相同。

接下来,我们截取表格视图的滚动

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    // Add some logic here to determine the section header. For example, use 
    // indexPathsForVisibleRows to get the visible index paths, from which you 
    // should be able to get the table view row that corresponds to the current 
    // section header. How this works will be implementation dependent.
    //
    // If the current section header has changed since the pervious scroll request 
    // (because a new one should now be at the top of the screen) then you should
    // update the contents.

    IndexPath *indexPathOfCurrentHeaderCell = ... // Depends on implementation
    UITableViewCell *headerCell = [self.tableView cellForRowAtIndexPath:indexPathOfCurrentHeaderCell];

    // If it exists then it's on screen. Hide our false header

    if (headerCell)
        self.cellHeader.hidden = true;

    // If it doesn't exist (not on screen) or if it's partially scrolled off the top,
    // position our false header at the top of the screen

    if (!headerCell || headerCell.frame.origin.y < self.tableView.contentOffset.y )
    {
        self.cellHeader.hidden = NO;
        self.cellHeader.frame = CGRectMake(0, self.tableView.contentOffset.y, self.cellHeader.frame.size.width, self.cellHeader.frame.size.height);
    }

    // Make sure it's on top of all other cells

    [self.tableView bringSubviewToFront:self.cellHeader];
}

最后,我们需要拦截对该单元格的操作并做正确的事情......

于 2012-06-12T13:29:42.693 回答
3

UITableView这是普通实例中节标题的默认行为。如果要创建自定义标题,tableView:viewForHeaderInSection:请在表视图委托中实现该方法并返回标题的视图。

尽管您将不得不管理部分和行,而不仅仅是行。

于 2012-06-05T09:21:22.770 回答
0

斯威夫特 5 解决方案

var header: UIView?

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(indexPath: indexPath) as UITableViewCell
    header = cell.contentView
    return cell
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let headerCell = tableView.cellForRow(at: IndexPath(row: 0, section: 0))
    guard headerCell == nil || (headerCell!.frame.origin.y < self.tableView.contentOffset.y + headerCell!.frame.height/2) else {
        header?.isHidden = true
        return
    }
    guard let hdr = header else { return }
    hdr.isHidden = false
    hdr.frame = CGRect(x: 0, y: tableView.contentOffset.y, width: hdr.frame.size.width, height: hdr.frame.size.height)
    if !tableView.subviews.contains(hdr) {
        tableView.addSubview(hdr)
    }
    tableView.bringSubviewToFront(hdr)
}
于 2019-06-25T14:47:50.263 回答