ios - 在 UITableView 单元格上快速求和值
问题描述
我有TableView
一个视图控制器和一个UILabel
。UIViewController
一切都得到了很好的展示,但我正在努力实现一些目标,我不能简单地得到它背后的逻辑。
tableview 单元格有一个 UILabel,它Int
在单元格上具有值,这些数字现在有所不同,我如何获得 tableView 单元格中标签上的数字总和并显示在视图控制器中的标签上。
我尝试在 UIView 控制器中创建一个变量并将这个值添加到 t 但我无法这样做,因为我无法将这个数字加在一起
关于如何做到这一点的任何帮助。谢谢
var total: Double?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! BrokageCheckoutCell
cell.configure()
total = Double("\(cell.subPrice.text!)")
cell.selectionStyle = .none
return cell
case 1:
let cell = tableView.dequeueReusableCell(withIdentifier: cellId2, for: indexPath) as! OtherCheckoutCell
cell.configure()
cell.selectionStyle = .none
return cell
default: break
}
return UITableViewCell()
}
解决方案
你问:
如何获取 tableView 单元格中标签上的数字总和并显示在视图控制器中的标签上
简而言之,你没有。表格视图单元格中的标签(它是“视图”的一部分)不是我们的数据源。它仅用于显示单个字符串。
例如,假设您的应用程序有 100 个要求和的项目,但应用程序的表格视图一次只显示 12 行。作为内存和性能改进,iOS 将重用滚动到视图之外的单元格,以便显示滚动到视图中的新行的内容。但这意味着您不能说“将这 100 个单元格中标签的所有内容相加”,因为没有 100 个单元格;只有12个。
您的应用程序应该引用它的“模型”,即cellForRowAt
用于确定在给定表格视图单元格中显示什么的结构(例如,数组)。所以,如果你想加总,你应该把那个数组中的值加起来,而不是引用单元格。
如果您的单元格具有允许修改数据的控件,则该单元格应启动模型的更新。然后,计算总计(对数组中的值求和)的过程仍然有效。
所以,让我们考虑一个例子:
您应该有一个模型,其中包含要求和的数字。您的示例有点不清楚,所以我将创建一个示例,其中每个表行包含一个名称、一个单价和一个数量:
struct Item { let name: String let unitPrice: Decimal var quantity: Decimal }
在此示例中,任何给定行的总计将是数量乘以单价。所有行的总计将是所有这些产品的总和。
然后你的视图控制器可能有一个数组用于它的模型:
var items: [Item] = ...
然后,当您想更新总计标签时,您只需使用一种方法计算每行总计的数量乘以价格,然后将这些值相加以计算总计。然后它将相应地更新总计文本字段:
private extension ViewController { func updateTotal() { let total = items .map { $0.quantity * $0.unitPrice } .reduce(0, +) totalLabel.text = totalFormatter.string(for: total) } }
请注意,我不是从单元格中检索这些数字(因为它们可能会被重复使用),而是从模型中检索我需要的所有数据。
但是,这里的关键是,例如,如果您的单元格允许用户更改其中一个值,那么您需要一种机制来更新表视图控制器的模型。我们将为此使用一个协议:
protocol ItemCellDelegate: class { func cell(_ cell: ItemCell, didUpdateQuantity quantity: Decimal) } class ItemCell: UITableViewCell { @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var quantityTextField: UITextField! @IBOutlet weak var unitPriceLabel: UILabel! static let quantityFormatter: NumberFormatter = ... static let priceFormatter: NumberFormatter = ... weak var delegate: ItemCellDelegate? }
显然,当您配置单元格时,视图控制器将指定更新文本字段(或其他)的委托:
// MARK: Public methods extension ItemCell { func configure(name: String, quantity: Decimal, unitPrice: Decimal, delegate: ItemCellDelegate) { self.delegate = delegate nameLabel.text = name quantityTextField.text = ItemCell.quantityFormatter.string(for: quantity) unitPriceLabel.text = ItemCell.priceFormatter.string(for: unitPrice) } }
当
ItemCell
获取更新时,它只是调用委托:// MARK: Private methods private extension ItemCell { @IBAction func didUpdateQuantity(_ sender: UITextField) { var quantity: Decimal? if let text = sender.text, let value = ItemCell.quantityFormatter.number(from: text) { quantity = value.decimalValue } delegate?.cell(self, didUpdateQuantity: quantity ?? 0) } }
然后,当视图控制器配置单元格时,它将自己提供为委托:
extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell let item = items[indexPath.row] cell.configure(name: item.name, quantity: item.quantity, unitPrice: item.unitPrice, delegate: self) return cell } }
而且,当然,视图控制器将遵循该协议来接受对文本字段的更新并更新模型:
extension ViewController: ItemCellDelegate { func cell(_ cell: ItemCell, didUpdateQuantity quantity: Decimal) { guard let indexPath = tableView.indexPath(for: cell) else { return } items[indexPath.row].quantity = quantity updateTotal() } }
而且,如您所见,如果可以的话,更新模型后,它也可以自动更新总数。
这里的关键是我们从不将单元格用作保存数据的地方。这些单元格仅用于(a)显示数据和(b)通知视图控制器是否需要注意任何更新。
我们努力实现非常清晰的职责分离,其中“视图”用于显示屏幕上的控件并与之交互,“模型”包含我们所有的数据。
推荐阅读
- mysql - 如何从 2 个时间表中获取所选时间?
- javascript - 如何禁用注入分隔符的 eslint 解析错误?
- javascript - 如何安装 moment.js 包并在 Ionic 应用程序中使用它?
- javascript - 从邮政编码javascript获取纬度和经度
- json - .JSON 文件无法正确打开
- azure - 我可以控制 API 管理门户容器的宽度吗?
- php - 在公共端点上使用 file_get_contents 时出现 400 错误
- file - 试图在 MAKE 文件中将文件从一个目录复制到另一个目录
- uri - URL 编码转义字符,如 \n、\t 等
- php - laravel 雄辩关系的问题