ios - 单元格一开始不出现,但如果我向下滚动并返回,则会显示

标签 ios swift uitableview

我有动态变化的表格 View 单元格,其中两个标签彼此重叠。顶部标签始终有一些文本,但底部标签有时没有。加载表格 View 后,底部标签没有文本的单元格完全消失,只显示标题。如果我向下滚动并返回,这些以前丢失的单元格会正确显示。

我认为这与我的约束有关,但是当我尝试调整约束时,我只会让事情变得更糟。

如何设置约束,使单元格始终在加载屏幕时首先出现,包括底部标签没有文本时?

这是表格 View 单元格的代码:

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

}

来自 View Controller 的代码:

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)

最佳答案

问题是,在添加任何 subview 并应用约束之前,您需要将其 translatesAutoresizing... 设置为 false

因此,您调用 configureItemNameLabel 并添加 sizeLabel调用 configureSizeLabel 并修复其 >翻译自动调整大小...

关于ios - 单元格一开始不出现,但如果我向下滚动并返回,则会显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56067867/

相关文章:

iphone - 释放时会发出内存泄漏警告,但自动释放时不会发出内存泄漏警告

ios - 尝试在 TableView 中配置两个单元格时出现 "Fatal error: Index out of range"错误

iOS UI View 大小

ios - UIPopoverController 内的 UINavigationController 'Back' 动画在风景中很奇怪

ios - 无法在 AudioFileStreamOpen 的 AudioFileStream_PacketsProc 回调中使用 AudioConverterFillComplexBuffer 将 mp3 转换为 PCM

ios - 尝试在 tableView :editActionsForRowAt: 中设置带有图像的按钮

arrays - Xcode swift TableView 仅显示一个数据值而不是全部

ios - dequeueReusableCellWithIdentifier :CellIdentifier how to avoid it

ios - Xcode-更改配置文件

swift - “ fatal error :在展开可选值时意外发现nil”是什么意思?