使 UITableView 部分标题与该部分的第一个单元格重叠 [英] Making UITableView section header overlap the first cell of the section

查看:54
本文介绍了使 UITableView 部分标题与该部分的第一个单元格重叠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我正在尝试实现您可以在 iOS 版 Google 日历应用中看到的类似功能(请参阅随附的屏幕截图).

查看左侧的日期标记 ({15, Tue}, {16, Wed}) 如何以与节标题浮动相同的方式浮动,并且在此外,它不是从该部分的第一个单元格上方开始,而是在与该部分的第一个单元格相同的 y 位置.

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

更新
好的,我已经设法靠近了.我注意到当我没有实现 tableView:heightForHeaderInSection: 方法时,我几乎得到了我所追求的确切行为 - 除了我失去了节标题的正常行为(一个节标题触摸前一个时将其推出屏幕).

找到了解决方案的开头.

之后的代码非常简单!

视图控制器:

class ViewController: UIViewController {@IBOutlet 弱变量 tableView:UITableView!覆盖 func viewDidLoad() {super.viewDidLoad()self.tableView.delegate = selfself.tableView.dataSource = selfself.tableView.register(UINib(nibName: "EventsTableViewCell", bundle: nil), forCellReuseIdentifier: "EventsCell")self.tableView.separatorStyle = .noneself.tableView.tableHeaderView?.frame = CGRect.zero}}扩展视图控制器:UITableViewDataSource {func numberOfSections(in tableView: UITableView) ->整数{返回 10}func tableView(_ tableView: UITableView, numberOfRowsInSection 部分: Int) ->整数{返回 1}func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->UITableViewCell {guard let cell = tableView.dequeueReusableCell(withIdentifier: "EventsCell") as?EventsTableViewCell 其他 {返回 UITableViewCell()}cell.dayLabel?.text = "\(indexPath.section)";cell.updateDayConstraint(scrollPosition: 0)//重置约束返回单元格}}扩展视图控制器:UITableViewDelegate {func scrollViewDidScroll(_ scrollView: UIScrollView) {如果让单元格 = tableView.visibleCells.first {如果让 c = 单元格为?EventsTableViewCell {让 position = scrollView.convert(scrollView.contentOffset, to: c).yc.updateDayConstraint(scrollPosition: 位置)}}}}

EventsTableViewCell:

class EventsTableViewCell: UITableViewCell {@IBOutlet 弱变量 dayLabel:UILabel!@IBOutlet 弱 var dayTopConstraint:NSLayoutConstraint!func updateDayConstraint(scrollPosition: CGFloat) {如果滚动位置 >0 {dayTopConstraint.constant = scrollPosition + 8} 别的 {dayTopConstraint.constant = 8//默认约束}}}

Is it possible to apply an offset to the section header views of a tableview similar to the way we can apply an inset to the tableview content?

I'm trying to achieve a similar thing that you can see in the Google Calendar for iOS app (See the attached screenshots).

See how the day marks on the left ({15, Tue}, {16, Wed}) is floating the same way a section header floats, and in addition its not starting above the first cell of the section, but in the same y position as the first cell in the section.

I'm using the tableView:viewForHeaderInSection: delegate method, and I'm getting the header via the dequeueReusableHeaderFooterViewWithIdentifier: of the tableview.
I'm creating the view using InterfaceBuilder.

UPDATE
Ok, I've manage to get closer. I've noticed that when I'm not implementing the tableView:heightForHeaderInSection: method, I almost get the exact behaviour I'm after - except I lose the normal behaviour of section headers (of one section header pushing the previous one out of the screen when it touches it).

Update screenshot 1
Update screenshot 2

As you can see on Update screenshot 1 the appearance is the requested one. Unfortunately, scrolling up a bit revealed I'm not yet there, as you can see in Update screenshot 2 - The headers overlaps each other, and the top one disappears when the bottom one reach to the same spot (instead of being pushed out).

It makes sense though, as both have zero height (since I haven't implemented the relevant delegate method, as I've mentioned earlier)

UPDATE 2
It seems I can't get to the exact behaviour without losing something in the way. I can get the section headers behaviour (each header pushing out the previous) but doing so I'm unable to remove the empty space of header size (returned in tableView:heightForHeaderInSection:).
On the other hand, I can remove the empty space, and get the section header to overlap the first cell, but doing so I also lose the normal section header behaviour (because they don't have a real height - you can see in the screenshot I've added in the previous update).

Original screenshots



Any help would be much appreciated. Thanks.

解决方案

I doubt this answer will still be useful to you, but maybe it will help others.

I tried to implement this behavior in the same way as you and, of course, I faced the same issues…

After some searches, I found the beginning of a solution here. Xuan-Gieng suggests using the scrollView's offset of the table view and passing it to the cells. So I used a UITableView without headers and I grouped the events of a same day into a UIStackView. A cell represents a day rather than an event, and the day number is at the top left of the cell view.

The top constraint of the day view has a priority of 750 and the bottom constraint has a "Greater Than or Equal" relation.

The code is pretty straightforward after that!

ViewController:

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
        }
    }

}

这篇关于使 UITableView 部分标题与该部分的第一个单元格重叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆