У меня есть динамически изменяющиеся ячейки таблицы, которые имеют две метки друг над другом.Верхняя метка всегда содержит текст, а нижняя - иногда нет.После загрузки табличного представления ячейки без текста для нижней метки полностью исчезают, и отображается только их заголовок.Если я прокручиваю вниз и возвращаюсь вверх, эти ранее отсутствующие ячейки отображаются правильно.
Я думаю, что это как-то связано с моими ограничениями, но когда я пытаюсь настроить ограничения, я только ухудшил положение.
Как сделать ограничения такими, чтобы ячейки всегда появлялись сначала при загрузке экрана, в том числе когда на нижней метке нет текста?
Вот код для ячейки табличного представления:
class TransactionHistoryTableViewCell: UITableViewCell {
private var itemView = UIView()
private var itemNameLabel = UILabel()
private var sizeLabel = UILabel()
func setup(_ lineItem: MenuItem) {
contentView.backgroundColor = .white
configureItemNameLabel(lineItem)
configureSizeLabel(lineItem)
configureTransactionView(lineItem)
}
private func configureTransactionView(_ lineItem: MenuItem) {
itemView.clipsToBounds = true
itemView.layer.cornerRadius = 5
itemView.layer.borderColor = UIColor.lightGray.cgColor
itemView.layer.borderWidth = 0.5
itemView.backgroundColor = .white
contentView.addSubview(itemView)
itemView.translatesAutoresizingMaskIntoConstraints = false
itemView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
itemView.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.8).isActive = true
itemView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 4).isActive = true
itemView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -4).isActive = true
}
private func returnText(_ menuItem: MenuItem) -> String {
var text = ""
guard let modifiers = menuItem.modifiers else { print("modifiers are nil"); return "" }
if modifiers.isEmpty && menuItem.quantity == 1 {
text = ""
} else if !modifiers.isEmpty && menuItem.quantity == 1 {
text = generateModifierText(menuItem)
} else if !modifiers.isEmpty && menuItem.quantity > 1 {
let theText = generateModifierText(menuItem)
text = "\(theText); Quantity: \(menuItem.quantity)"
} else {
text = "Quantity: \(menuItem.quantity)"
}
return text
}
private func configureItemNameLabel(_ lineItem: MenuItem) {
itemNameLabel.text = lineItem.name
let fontSize = getSize(large: 14, medium: 13.5, small: 12)
itemNameLabel.font = UIFont(name: AppFont.secondary.name, size: fontSize)
itemNameLabel.numberOfLines = 0
itemView.addSubview(itemNameLabel)
itemNameLabel.translatesAutoresizingMaskIntoConstraints = false
itemNameLabel.leftAnchor.constraint(equalTo: itemView.leftAnchor, constant: 15).isActive = true
let verticalOffset = getSize(large: 10, medium: 7, small: 5)
itemNameLabel.topAnchor.constraint(equalTo: itemView.topAnchor, constant: verticalOffset).isActive = true
itemNameLabel.widthAnchor.constraint(equalToConstant: 195).isActive = true
itemView.addSubview(sizeLabel)
itemNameLabel.bottomAnchor.constraint(equalTo: sizeLabel.topAnchor, constant: -3).isActive = true
}
func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{
let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.font = font
label.text = text
label.sizeToFit()
return label.frame.height
}
override func prepareForReuse() {
super.prepareForReuse()
itemNameLabel.text = ""
sizeLabel.text = ""
}
private func configureSizeLabel(_ menuItem: MenuItem) {
guard let modifiers = menuItem.modifiers else { print("modifiers are nil"); return }
if modifiers.isEmpty && menuItem.quantity == 1 {
sizeLabel.text = ""
} else if !modifiers.isEmpty && menuItem.quantity == 1 {
sizeLabel.text = generateModifierText(menuItem)
} else if !modifiers.isEmpty && menuItem.quantity > 1 {
let text = generateModifierText(menuItem)
if text != "" {
sizeLabel.text = "\(text); Quantity: \(menuItem.quantity)"
} else {
sizeLabel.text = "Quantity: \(menuItem.quantity)"
}
} else {
sizeLabel.text = "Quantity: \(menuItem.quantity)"
}
sizeLabel.backgroundColor = .white
sizeLabel.textColor = .gray
sizeLabel.numberOfLines = 0
let fontSize = getSize(large: 11, medium: 10.5, small: 9.5)
sizeLabel.font = UIFont(name: AppFont.secondary.name, size: fontSize)
sizeLabel.translatesAutoresizingMaskIntoConstraints = false
sizeLabel.topAnchor.constraint(equalTo: itemNameLabel.bottomAnchor, constant: 3).isActive = true
sizeLabel.leftAnchor.constraint(equalTo: itemNameLabel.leftAnchor).isActive = true
sizeLabel.widthAnchor.constraint(equalToConstant: 200).isActive = true
sizeLabel.bottomAnchor.constraint(equalTo: itemView.bottomAnchor, constant: -3).isActive = true
}
private func generateModifierText(_ menuItem: MenuItem) -> String {
var text = ""
guard let modifiers = menuItem.modifiers else { return "" }
var optionNames = [String]()
for modifier in modifiers {
if !modifier.options.isEmpty {
for options in modifier.options{
if options.name.uppercased() != "NONE" {
optionNames.append(options.name)
}
}
}
}
for x in 0..<optionNames.count {
if x != optionNames.count - 1 {
text += "\(optionNames[x]), "
} else {
text += "\(optionNames[x])"
}
}
return text
}
private func generateSizeLabelFontSize() -> CGFloat {
return getSize(large: 11, medium: 10, small: 9.5)
}
}
Код из контроллера представления:
override func viewDidLoad() {
super.viewDidLoad()
configureNavBar()
configureTableView()
getOrders()
NotificationCenter.default.addObserver(self, selector: #selector(popToRootVC), name: NSNotification.Name(rawValue: "PopToRootVCFromSettingsVC"), object: nil)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "transactionHistoryCell", for: indexPath) as? TransactionHistoryTableViewCell else { getOrders(); return UITableViewCell() }
if let lineItem = orders[indexPath.section].lineItems?[indexPath.row] {
cell.setup(lineItem)
}
return cell
}
private func getOrders() {
let service = TransactionService()
service.getTransactionData(completion: { (orders) in
guard let orders = orders else { self.handleNoOrderHistory(); return }
let filteredOrders = orders.filter{ $0.status == "NEW" || $0.status == "IN_PROGRESS" || $0.status == "READY" || $0.status == "COMPLETE" }
if filteredOrders.isEmpty {
DispatchQueue.main.async {
self.handleNoOrderHistory()
return
}
} else {
DispatchQueue.main.async {
self.orders = filteredOrders.sorted{ $0.date > $1.date }
self.noOrdersView.isHidden = true
self.tableView.reloadData()
}
}
})
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 85
}
Компилятор выдает такие предупреждения:
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
NSAutoresizingMaskLayoutConstraint:0x600001e972a0 h=--& v=--& UILabel:0x7f9a0050b780.midY == 0 (active),
NSAutoresizingMaskLayoutConstraint:0x600001e97610 h=--& v=--& UILabel:0x7f9a0050b780.height == 0 (active),
NSLayoutConstraint:0x600001e8bca0 V:|-(5)-[UILabel:0x7f9a0050b490'5\" Focaccia Everything'] (active, names: '|':UIView:0x7f9a0050b2b0 ),
NSLayoutConstraint:0x600001d63660 UILabel:0x7f9a0050b490'5\" Focaccia Everything'.bottom == UILabel:0x7f9a0050b780.top - 3 (active)
)
Will attempt to recover by breaking constraint
NSLayoutConstraint:0x600001d63660 UILabel:0x7f9a0050b490'5" Focaccia Everything'.bottom == UILabel:0x7f9a0050b780.top - 3 (active)