【问题标题】:Adding top and bottom constraints causes UILable to be squished添加顶部和底部约束会导致 UILabel 被压扁
【发布时间】:2020-11-03 08:09:49
【问题描述】:

我以编程方式创建了一个自定义 UITableViewCell 并尝试在其中垂直居中两个 UILabel。但 UILabel 最终被压扁了。在 Interface Builder 中用原型单元做同样的事情效果很好。我的代码有什么问题?

自定义视图单元格类

import UIKit

class TopViewCell: UITableViewCell {
    let df: DateFormatter = {
        let df = DateFormatter()
        df.dateFormat = NSLocalizedString("DATE_WEEKDAY", comment: "show date and weekday")
        return df
    }()
    var dateLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    var costLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        let margin = contentView.layoutMarginsGuide
        
        contentView.addSubview(dateLabel)
        dateLabel.leadingAnchor.constraint(equalTo: margin.leadingAnchor).isActive = true
        dateLabel.topAnchor.constraint(equalTo: margin.topAnchor).isActive = true
        dateLabel.bottomAnchor.constraint(equalTo: margin.bottomAnchor).isActive = true
        
        contentView.addSubview(costLabel)
        costLabel.trailingAnchor.constraint(equalTo: margin.trailingAnchor).isActive = true
        costLabel.topAnchor.constraint(equalTo: dateLabel.topAnchor).isActive = true
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        dateLabel.text = df.string(from: Date())
        costLabel.text = "total: five thousand"
    }
}


自定义 UITableViewController 类

import UIKit

class ItemViewController: UITableViewController {
    var itemStore: ItemStore!

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(TopViewCell.self, forCellReuseIdentifier: "top_cell")
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return itemStore.allItems.count + 1
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell: UITableViewCell!
        
        if indexPath.row == 0 {
            cell = tableView.dequeueReusableCell(withIdentifier: "top_cell", for: indexPath)
        } else {
            cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            cell.textLabel?.text = itemStore.allItems[indexPath.row - 1].name
            cell.textLabel?.font = cell.textLabel!.font.withSize(30)
            cell.detailTextLabel?.text = "$\(itemStore.allItems[indexPath.row - 1].valueInDolloar)"
        }
        
        return cell
    }
}

【问题讨论】:

  • 您有 2 个或 3 个标签吗? Book/Bike 标签有什么限制?请张贴所有的东西
  • @Sh_Khan 我更新了屏幕截图,以便您更好地理解它。 tableView 实际上使用了 2 种类型的 UITableViewCells:最上面的一种,它包含“total:五千”文本,是用我的自定义类“TopViewCell”创建的;而其他单元格由具有默认 UITableViewCell 类的 Interface Builder 原型单元格创建,该类使用“正确的细节”样式。

标签: ios swift uitableview autolayout nslayoutconstraint


【解决方案1】:

您的 TopViewCell 未正确自动调整大小,因为您在 layoutSubviews() 中设置了文本。将这两行移至init,它的大小会正确:

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    
    let margin = contentView.layoutMarginsGuide
    
    contentView.addSubview(dateLabel)
    dateLabel.leadingAnchor.constraint(equalTo: margin.leadingAnchor).isActive = true
    dateLabel.topAnchor.constraint(equalTo: margin.topAnchor).isActive = true
    dateLabel.bottomAnchor.constraint(equalTo: margin.bottomAnchor).isActive = true
    
    contentView.addSubview(costLabel)
    costLabel.trailingAnchor.constraint(equalTo: margin.trailingAnchor).isActive = true
    costLabel.topAnchor.constraint(equalTo: dateLabel.topAnchor).isActive = true

    // set the text here
    dateLabel.text = df.string(from: Date())
    costLabel.text = "total: five thousand"
}

附带说明,您应该在使用TopViewCell时指定类:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
    if indexPath.row == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "top_cell", for: indexPath) as! TopViewCell
        return cell
    }
        
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = itemStore.allItems[indexPath.row - 1].name
    cell.textLabel?.font = cell.textLabel!.font.withSize(30)
    cell.detailTextLabel?.text = "$\(itemStore.allItems[indexPath.row - 1].valueInDolloar)"

    return cell
}

另外说明...您可以在情节提要中创建两个原型单元。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多