我希望能够在用户滚动时修复UITableView中某些行的位置。
具体来说,我有一个表,其中某些行是后续行的“标题”,我希望当用户向上滚动时标题保持在屏幕顶部。当用户滚动到足以使下一个标题行取代它时,它将会移开。
类似的例子是Any.DO应用程序。 “今天”,“明天”和“稍后”表格行始终显示在屏幕上。
有没有人对如何实施这一点有任何建议?
我目前正在考虑遵循TableDidScroll委托并将我自己的单元格放置在表视图前面的适当位置。问题是,在其他时候,我真的希望这些单元格成为真正的表格单元格,以便它们可以由用户重新排序。
谢谢,
添
答案 0 :(得分:13)
我一直在玩这个,我想出了一个简单的解决方案。
首先,我们向控制器添加一个UITableViewCell属性。这应该初始化,使其看起来与我们将用于创建false节标题的行单元格完全相同。
接下来,我们拦截表格视图的滚动
- (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];
}
最后,我们需要拦截对该单元格的操作并做正确的事情......
答案 1 :(得分:3)
这是普通UITableView
实例中节标题的默认行为。
如果要创建自定义标头,请在表视图委托中实施tableView:viewForHeaderInSection:
方法,并返回标头的视图。
虽然您必须管理部分和行而不仅仅是行。
答案 2 :(得分:0)
Swift 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)
}