使UITableView节标题重叠该节的第一个单元格

时间:2016-03-15 13:10:45

标签: ios objective-c uitableview

是否可以将偏移量应用于tableview的节标题视图,类似于我们可以将插入内容应用于tableview内容的方式?

我试图在Google Calendar for iOS应用中看到类似的内容(请参阅随附的屏幕截图)。

查看左侧的日标记({15, Tue}{16, Wed})是如何浮动的,与标题标题浮动的方式相同,此外它不是从开始第一个该部分的单元格,但与该部分中的第一个单元格位于相同的y位置。

我使用tableView:viewForHeaderInSection:委托方法,并通过tableview的dequeueReusableHeaderFooterViewWithIdentifier:获取标题。
我正在使用InterfaceBuilder创建视图。

更新
好的,我已经设法靠近了。我注意到,当我没有实现tableView:heightForHeaderInSection:方法时,我几乎得到了我之后的确切行为 - 除了我丢失了节标题的正常行为(一节节目标题)当它接触时将前一个推出屏幕。)

Update screenshot 1
Update screenshot 2

正如您在Update screenshot 1上看到的那样,外观是所要求的。不幸的是,向上滚动显示我还没有,正如你在Update screenshot 2中看到的那样 - 标题彼此重叠,顶部标题在底部到达同一位置时消失(而不是被推出)。

这很有意义,因为它们都没有高度(因为我还没有实现相关的委托方法,正如我之前提到的那样)

更新2
似乎我无法在不丢失某些东西的情况下达到确切的行为。我可以获得节标题行为(每个标题推出前一个标题)但是这样做我无法删除标题大小的空白空间(在tableView:heightForHeaderInSection:中返回)。
另一方面,我可以删除空白区域,并获取节标题与第一个单元格重叠,但这样做我也失去了正常的节标题行为(因为它们没有真正的高度 - 你可以看到在我之前的更新中添加的屏幕截图中。

原始屏幕截图

Screenshot 1
Screenshot 2
Screenshot 3

非常感谢任何帮助。感谢。

2 个答案:

答案 0 :(得分:0)

是的,这是可能的。为此,您需要使用一个UIView,它具有清晰的背景,左侧只有一个标签,如图所示。我们使这个UIView位的高度更大,然后重叠约。一个部分中的第一行,此UIView中的Label将垂直居中。我们将这个UIView返回给UITableview的viewForHeaderInSection。 希望这可能有所帮助。

答案 1 :(得分:0)

我怀疑这个答案对您仍然有用,但也许它会帮助其他人。

我尝试以与您相同的方式实现此行为,当然,我遇到了相同的问题......

经过一番搜索,我找到了解决方案here的开头。 Xuan-Gieng 建议使用表格视图的 scrollView 偏移量并将其传递给单元格。所以我使用了一个没有标题的 UITableView,并将同一天的事件分组到一个 UIStackView 中。一个单元格代表一天而不是一个事件,天数位于单元格视图的左上角。

日视图的顶部约束的优先级为 750,底部约束具有“大于或等于”关系。

enter image description here

之后的代码非常简单!

视图控制器:

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.tableView.delegate = self
        self.tableView.dataSource = self
        self.tableView.register(UINib(nibName: "EventsTableViewCell", bundle: nil), forCellReuseIdentifier: "EventsCell")
        self.tableView.separatorStyle = .none
        self.tableView.tableHeaderView?.frame = CGRect.zero
    }

}

extension ViewController: UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 10
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "EventsCell") as? EventsTableViewCell else {
            return UITableViewCell()
        }
        cell.dayLabel?.text = "\(indexPath.section)"
        cell.updateDayConstraint(scrollPosition: 0) // To reset the constraint
        return cell
    }

}

extension ViewController: UITableViewDelegate {

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if let cell = tableView.visibleCells.first {
            if let c = cell as? EventsTableViewCell {
                let position = scrollView.convert(scrollView.contentOffset, to: c).y
                c.updateDayConstraint(scrollPosition: position)
            }
        }
    }

}

EventsTableViewCell:

class EventsTableViewCell: UITableViewCell {

    @IBOutlet weak var dayLabel: UILabel!
    @IBOutlet weak var dayTopConstraint: NSLayoutConstraint!

    func updateDayConstraint(scrollPosition: CGFloat) {
        if scrollPosition > 0 {
            dayTopConstraint.constant = scrollPosition + 8
        } else {
            dayTopConstraint.constant = 8 // Default constraint
        }
    }

}