添加顶部和底部约束会导致压缩UILable

时间:2020-07-14 03:23:57

标签: ios swift uitableview autolayout nslayoutconstraint

我以编程方式创建了一个自定义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
    }
}

enter image description here

enter image description here

1 个答案:

答案 0 :(得分: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
}

请注意,您可以在情节提要中创建两个原型单元。