如何在表格视图的各部分中修复单元格的分离集合? [英] How to fix the separation collections of cells in my sections in my tableview?
问题描述
因此有人告诉我,将单元格划分为多个部分的数据模型是不好的.
So I've been told that my data model for separating my cells into sections is bad.
我在Tableview的cartItems,groupedItems和brandVC中有3个单独的集合.有人告诉我:
I have 3 separate collections in my Tableview cartItems, groupedItems, and brandTitle in the CartVC. and I've been told this:
您需要从一个仅代表截面数据的集合开始(每个截面数据将保存相应的行数据),这样您就可以对模型进行修改而不会发疯"
"You need to start over with a single collection representing nothing but sections data (where each piece of section data will hold the corresponding row data), so you can mutate the model without going insane"
和
"......建议避免为表视图的数据源使用多个数组,并使用Dictionary来馈送表视图不是一个好主意.您应该创建一个Model类型."
"...recommended to avoid multiple Arrays for the datasource of a table view and using Dictionary to feed the table view is not a good idea. You should create a Model type."
我只是真的不知道该怎么做,因为我一直在使用这些集合将单元格划分为几个部分,因此我花了数周的时间来生成并弄清楚这些,以便我可以成功地将单元格填充到适当的部分中在CartVC中
I just don't know really how to do so, since the collections I've been using to separate the cells into sections took me weeks to generate and figure out, so that I could successfully populate the cells in their appropriate sections in the CartVC
import UIKit
class CartViewController: UIViewController {
var selectedProduct: ItemList! // allows data to be passed into the CartVC
// allows data to be sepearted into sections
var cartItems: [CartItem] = []
var groupedItems: [String: [CartItem]] = [:]
var brandTitle: [String] = []
@IBOutlet weak var cartTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
groupedItems = Dictionary(grouping: cartItems, by: {$0.itemList.brandName})
brandTitle = groupedItems.map{$0.key}.sorted()
}
}
extension CartViewController: UITableViewDelegate, UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return brandTitle.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let brand = brandTitle[section]
return groupedItems[brand]!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cartCell = tableView.dequeueReusableCell(withIdentifier: "CartCell") as! CartCell
let brand = brandTitle[indexPath.section]
let itemsToDisplay = groupedItems[brand]![indexPath.row]
cartCell.configure(withCartItems: itemsToDisplay.productList)
return cartCell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cartHeader = tableView.dequeueReusableCell(withIdentifier: "CartHeader") as! CartHeader
let headerTitle = brandTitle[section]
cartHeader.brandName.text = "Brand: \(headerTitle)"
return cartHeader
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 45
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let cartFooter = tableView.dequeueReusableCell(withIdentifier: "CartFooter") as! CartFooter
let brand = brandTitle[section]
let subtotal = groupedItems[brand]?.map { $0.getCartTotal() }.reduce(0, +) ?? 0
cartFooter.cartTotal.text = String(subtotal)
return cartFooter
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 150
}
import Foundation
class CartItem {
var itemList: ItemList!
init(itemList: ItemList) {
self.itemList = itemList
}
func getCartTotal() -> Float {
var subtotal: Float = 0
if itemList.selectedOption == 1 {
subtotal = subtotal + (Float(itemList.price1) * Float(itemList.count))
} else if itemList.selectedOption == 2 {
subtotal = subtotal + (Float(itemList.price2) * Float(itemList.count))
} else if itemList.selectedOption == 3 {
subtotal = subtotal + (Float(itemList.price3) * Float(itemList.count))
} else {
fatalError("The impossible happend")
}
return subtotal
}
}
class ItemList {
var id: String
var name: String
var brand: String
var price1: Float
var price2: Float
var price3: Float
var weight1: String
var weight2: String
var weight3: String
var imageUrl: String
var selectedOption: Int
var count: Int
init(id: String,
name: String,
brand: String,
price1: Float,
price2: Float,
price3: Float,
weight1: String,
weight2: String,
weight3: String,
imageUrl: String,
selectedOption: Int,
count: Int) {
self.id = id
self.name = name
self.brand = brand
self.price1 = price1
self.price2 = price2
self.price3 = price3
self.weight1 = weight1
self.weight2 = weight2
self.weight3 = weight3
self.imageUrl = imageUrl
self.selectedOption = selectedOption
self.count = count
}
convenience init(dictionary: [String : Any]) {
let id = dictionary["id"] as? String ?? ""
let name = dictionary["name"] as? String ?? ""
let brand = dictionary["brand"] as? String ?? ""
let price1 = dictionary["price1"] as? Float ?? 0.0
let price2 = dictionary["price2"] as? Float ?? 0.0
let price3 = dictionary["price3"] as? Float ?? 0.0
let weight1 = dictionary["weight1"] as? String ?? ""
let weight2 = dictionary["weight2"] as? String ?? ""
let weight3 = dictionary["weight3"] as? String ?? ""
let imageUrl = dictionary["imageUrl"] as? String ?? ""
let selectedOption = dictionary["selectedOption"] as? Int ?? 00
let count= dictionary["count"] as? Int ?? 00
self.init(id: id,
name: name,
brand: brand,
price1: price1,
price2: price2,
price3: price3,
weight1: weight1,
weight2: weight2,
weight3: weight3,
imageUrl: imageUrl,
selectedOption: selectedOption,
count: count)
}
}
推荐答案
假设您所有购物车商品中只有 1个部分.您的模型会有什么?
Imagine you have just one section of all your cart items. What would you have as your model?
- 标题
- 一系列购物车商品
对吗?
好的,如果上面的讲得通,那么您将需要所述模型类型的倍数.再说一次现在,将其分解为更具体的术语.类似于实际的模型类型.除非您确实需要引用语义,否则总是建议从模型的值类型开始.
Okay if the above makes sense, you then would need multiple of that said model type. Right again? Now break that into more specific terms. Like actual model type. It's always good and recommended to start with value type for the models unless you really need the reference semantics.
struct CartItem {
// intentionally renamed the ItemList to CartItem and stripped out most of the properties
let name: String
let brand: String
}
struct Section {
let title: String
let cartItems: [CartItem]
}
我不会自己初始化Section
的数组,更多的是实现细节.但是,如果您必须从外部类型(例如 JSON )进行初始化,则可能需要 compactMap( :) 或减少(in :: _ :) .基本上,您将需要 一般转换Collection
的想法.或者也可以可编码.
I'm not going to initialize the array of Section
s by myself, it's more of an implementation detail. But if you have to initialize that from external types (such as JSON) you may need the help of map(:), compactMap(:) or reduce(into:_:). Basically you will need the idea of Transforming a Collection
in general. Or maybe Codable too.
那么您如何将上述Section
类型与UITableView
一起使用?仔细观察:
So how do you use the above Section
type with your UITableView
? Look closely:
class CartViewController: UIViewController {
. . .
// left out for the reader to initialize on his own
let sections = [Section]()
. . .
. . .
}
extension CartViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
. . .
let cartItem = sections[indexPath.section].cartItems[indexPath.row]
. . .
}
}
现在CartViewController
中的所有其他位置,您将访问sections
数组,并且将始终指向正确的对象.
Now every other places in your CartViewController
you will access the sections
array and you will always be pointing to the right object.
深入研究模型操作.您可以在模型类型本身中为不同的表示形式使用不同的辅助函数.像:
Diving deep into the model manipulation. You can have different helper functions in your model type itself for different representations. Like:
struct Section {
let title: String
let cartItems: [CartItem]
static func groupedSectionsByBrand(from cartItems: [CartItem]) -> [Section] {
let grouped = Dictionary(grouping: cartItems) { $0.brand }
let sections = grouped.map { Section(title: $0.key, cartItems: $0.value) }
return sections
}
}
然后,您将可以通过仅传递CartItem
的数组来生成所需的Section
数组,例如:
Then you will be able to generate your desired array of Section
by passing only the array of CartItem
like:
let cartItems = [CartItems]() // have these values from elsewhere
let sections = Section.groupedSectionsByBrand(from: cartItems)
这篇关于如何在表格视图的各部分中修复单元格的分离集合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!