行分隔符上的标签 - Swift Tableview - 每小时日历

Posted

技术标签:

【中文标题】行分隔符上的标签 - Swift Tableview - 每小时日历【英文标题】:Label on Row Separator - Swift Tableview - Hourly Calendar 【发布时间】:2018-01-07 09:30:58 【问题描述】:

我想创建一个相对基本但类似于 Apple 原生日历视图的小时日历视图。如何添加标签以与行/单元格分隔符一致,并且不包含在单元格中。像这样:

是否有一个属性可以让您为线条添加标签?标签是否必须放置在表格视图之外?还是有单独的表出现?

就创建彩色块来表示日历上的事件而言,最好的方法是什么?它只是原型单元格中的 CGRect 吗?您需要创建单独的 xib 文件吗?

提前感谢您的帮助,我还是新手!

【问题讨论】:

How to customize tableView separator in iPhone的可能重复 【参考方案1】:

这是不可能的(或者从技术上讲,这是可能的,但是考虑到您的其他选择,开销太高了)。

不使用单元格分隔符,而是设置separatorStyle = .none,并在单元格中画线(例如,作为UIViewview.height = 1view.backgroundColor = .grey)并通常在单元格中添加标签。

基本上解决方案非常简单:禁用标准分隔线,而是在单元格(底部或顶部)内绘制分隔符以及标签。当客户要求一些自定义花式分隔符时,我就是这样做的 - 我在单元格底部添加了一条自定义行,并使用单元格的其余部分 contentView 作为单元格的内容。

编辑

您可以使用以下示例开始(请注意,这只是管理它的几种不同方法之一):

class TimeCellViewController: UITableViewController 
    override func loadView() 
        super.loadView()

        // you can use UITableViewAutomaticDimension instead of static height, if
        // there will be variable heights that you don't know upfront
        // https://***.com/a/18746930/2912282
        // or mine:
        // https://***.com/a/47963680/2912282
        tableView.rowHeight = 80
        tableView.estimatedRowHeight = 80

        tableView.separatorStyle = .none

        // to allow scrolling below the last cell
        tableView.tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 40))

        tableView.register(TimeCell.self, forCellReuseIdentifier: "timeCell")
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return 24
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "timeCell", for: indexPath) as! TimeCell
        if indexPath.row > 0 
            cell.topTime = "\(indexPath.row):00"
         else 
            cell.topTime = ""
        
        cell.bottomTime = "\(indexPath.row + 1):00"
        return cell
    


class TimeCell: UITableViewCell 
    // little "hack" using two labels to render time both above and below the cell
    private let topTimeLabel = UILabel()
    private let bottomTimeLabel = UILabel()

    private let separatorLine = UIView()

    var topTime: String = "" 
        didSet 
            topTimeLabel.text = topTime
        
    
    var bottomTime: String = "" 
        didSet 
            bottomTimeLabel.text = bottomTime
        
    

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) 
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        selectionStyle = .none

        contentView.addSubview(topTimeLabel)
        contentView.addSubview(bottomTimeLabel)
        contentView.addSubview(separatorLine)


        topTimeLabel.textColor = UIColor.gray
        topTimeLabel.textAlignment = .right
        bottomTimeLabel.textColor = UIColor.gray
        bottomTimeLabel.textAlignment = .right
        separatorLine.backgroundColor = UIColor.gray

        bottomTimeLabel.translatesAutoresizingMaskIntoConstraints = false
        topTimeLabel.translatesAutoresizingMaskIntoConstraints = false
        separatorLine.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            bottomTimeLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0),
            bottomTimeLabel.centerYAnchor.constraint(equalTo: self.bottomAnchor),
            bottomTimeLabel.widthAnchor.constraint(equalToConstant: 50),
            topTimeLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0),
            topTimeLabel.centerYAnchor.constraint(equalTo: self.topAnchor),
            topTimeLabel.widthAnchor.constraint(equalToConstant: 50),
            separatorLine.leftAnchor.constraint(equalTo: bottomTimeLabel.rightAnchor, constant: 8),
            separatorLine.bottomAnchor.constraint(equalTo: self.bottomAnchor),
            separatorLine.heightAnchor.constraint(equalToConstant: 1),
            separatorLine.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0),
            ])

        // if you use UITableViewAutomaticDimension instead of static height,
        // you will have to set priority of one of the height constraints to 999, see
        // https://***.com/q/44651241/2912282
        // and
        // https://***.com/a/48131525/2912282
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

【讨论】:

页眉/页脚也可以用来实现这一点 是的,但是他将不得不去每个单元格..虽然在他的特殊情况下这不一定是问题.. 对于包含跨越多个单元格/行的事件块的日历,此解决方案是否仍然有效?那么每个单元格的顶部不会有一个小空白,这意味着一个块在单元格顶部的位置也会有空白吗? 为什么不呢?在这种方法中,整个单元格都在您的控制之下 - 如果您实施单元格以便有一个空格,那么就会有一个空格。如果你实现它没有空格,就不会有空格。 是的,我明白你的意思.. 好吧,这并不容易,但你可以做一些小技巧,通过在两个单元格中呈现标签,让它看起来像真正的分隔符(然后看起来标签正好在两个单元格之间)..我将更新我的答案以包含一个小示例供您开始

以上是关于行分隔符上的标签 - Swift Tableview - 每小时日历的主要内容,如果未能解决你的问题,请参考以下文章

iOS Swift ScrollView、UITableView、滚动区域

如何在 UICollectionView、Swift 5、Xcode 的行下添加行

插入行后 UITableViewCell 动态高度中断

Swift 4 - 标签栏项目上的按钮

Swift 3 - UTC 到时间前标签,考虑 12 小时 / 24 小时设备时间变化

ng2-charts数据标签上的千位分隔符