您如何在表格视图中对部分进行分组?

时间:2019-10-17 15:18:30

标签: ios arrays swift tableview sections

我想做的是将TableView中的部分分组。通过按storeName对它们进行排序,以便我可以将各项分开以转到其适当的部分并按StoreName进行排列。

我正在尝试为每个商店在列表中显示几个不同部分的项目。通过基于StoreName对部分进行分组。

Items数组在每个部分中包含每个项目的所有项目,并显示该项目所属的存储。

如何将特定商店的板块分组?

我知道我很接近将我的部分分组,但是我只是不确定如何使其正确运行以及如何连接到我的Custom HeaderCell。我在自己的StoreVC中编写了一个名为attemptToAssembleStoreGroups()

的函数

我只想知道如何将他们的商品按他们的storeName分组在一起,以便每个商店都有自己的版块并有自己的商品列表。

struct ItemSelection {
    let store: String
    let productName: String
    let productImage: UIImage
    let quantity: String
    let total: String
}

struct ItemSection {
    let title : String
    let stores : [ItemSelection]
}

class StoreVC: UITableViewController {

      fileprivate let cellId = "id123"

        let items = [
          ItemSelection(store: "Walmart",
               productName: "Bionicle",
               productImage: #imageLiteral(resourceName: "Bionicle"),
               quantity: "4",
               total: "24"),
          ItemSelection(store: "Walmart",
               productName: "PokeBall",
               productImage: #imageLiteral(resourceName: "PokeBall"),
               quantity: "2",
               total: "30"),
          ItemSelection(store: "Target",
               productName: "Beer",
               productImage: #imageLiteral(resourceName: "Beer"),
               quantity: "2",
               total: "30"),
          ItemSelection(store: "Lego Store",
               productName: "Star Wars Set",
               productImage: #imageLiteral(resourceName: "Star_Wars_Set"),
               quantity: "4",
               total: "256"),
          ItemSelection(store: "Lego Store",
               productName: "Indiana Jones Set",
               productImage: #imageLiteral(resourceName: "Indiana_Jones_Set"),
               quantity: "2",
               total: "88"),
          ItemSelection(store: "Amazon",
               productName: "Coconut Milk",
               productImage: #imageLiteral(resourceName: "Coconut_Milk"),
               quantity: "4",
               total: "20"),
          ItemSelection(store: "Amazon",
               productName: "32 inch Tv",
               productImage: #imageLiteral(resourceName: "TV"),
               quantity: "1",
               total: "156"),
          ItemSelection(store: "Amazon",
               productName: "Amazon Echo",
               productImage: #imageLiteral(resourceName: "Amazon_Echo"),
               quantity: "1",
               total: "80"),
          ItemSelection(store: "Amazon",
               productName: "Grill",
               productImage: #imageLiteral(resourceName: "Grill"),
               quantity: "3",
               total: "90"),
          ItemSelection(store: "Amazon",
               productName: "Coconut Bar",
               productImage: #imageLiteral(resourceName: "coconuts"),
               quantity: "4",
               total: "240")
         ]

      var itemSelection = [[ItemSelection]]()
      var storeArray = [String]()
      var itemSections = [ItemSection]()

     override func viewDidLoad() {
        super.viewDidLoad()

        for index in self.items {
            storeArray.append(index.store)
        }

        let groupedDictionary = Dictionary(grouping: items, by: {String($0.store.prefix(1))})
        let keys = groupedDictionary.keys.sorted()
        itemSections = keys.map{ItemSection(title: $0, stores: groupedDictionary[$0]!.sorted(by: {$0.store < $1.store}))}
     }



     override func numberOfSections(in tableView: UITableView) -> Int {
         return itemSections.count
     }

     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
         return itemSections[section].stores.count
     }

     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! StoreCell
         let itemSelections = itemSelection[indexPath.section][indexPath.row]
         cell.itemSelction = itemSelections
         return cell
     }

     override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
         let cartHeader = tableView.dequeueReusableCell(withIdentifier: "Header") as! HeaderCell

         let stores = itemSelection[section]

         cartHeader.storeName.text = "Store: \(stores)"

         return cartHeader
     }

     override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
         return 45
     }

}

class StoreCell: UITableViewCell {

    @IBOutlet weak var itemQty: UILabel!
    @IBOutlet weak var itemName: UILabel!
    @IBOutlet weak var itemPrice: UILabel!
    @IBOutlet weak var itemImage: UIImage!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

    var itemSelection: ItemSelection! {
        didSet {
            itemName.text = itemSelection.productName
            itemQty.text = "Qty: \(itemSelection.quantity)"
            itemPrice.text = "$\(itemSelection.total)"
            itemImage.image = itemSelection.productImage
        }

    }

}

class HeaderCell: UITableViewCell {

    @IBOutlet weak var storeName: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

2 个答案:

答案 0 :(得分:1)

找到我的解决方案

r

import Foundation

struct Items {
    let store: String
    let productName: String
    let productImage: UIImage
    let quantity: String
    let price: String
}

extension Items: Comparable {
    static func < (lhs: Items, rhs: Items) -> Bool {
        if lhs.store < rhs.store { return true }
        else { return lhs.store == rhs.store && lhs.productName < rhs.productName }
    }
}

extension Items {
    static let retail: [Items] = [
        .init(store: "Amazon",
              productName: "Care Bear",
              productImage: #imageLiteral(resourceName: "Bear"),
              quantity: "4",
              price: "156"),
        .init(....
    ]
}

import Foundation

class ItemDataSource: NSObject {
    var sections: [String: [Items]] = [:]

    var items: [String] {
        return sections.keys.sorted()
    }

    var indexes: [String] {
        return items
            .map { String($0.first!) }
            .reduce(into: Set<String>(), { $0.insert($1) })
            .sorted()
    }

    init(stores: [Items]) {
        for store in retail.sorted(by: <) {
            let items = store.items
            if var stores = sections[items] {
                stores.append(store)
                sections[items] = stores
            } else {
                sections[items] = [store]
            }
        }
    }
}

class StoreHeader: UITableViewCell {

    @IBOutlet weak var dispensaryName: UILabel!

    var store: String? {
        didSet { storeName.text = "Store: \(store!)" }
    }

}

class StoreCell: UITableViewCell {

    @IBOutlet weak var productImage: UIImageView!
    @IBOutlet weak var productQty: UILabel!
    @IBOutlet weak var productPrice: UILabel!
    @IBOutlet weak var productName: UILabel!

    var product: String? {
        didSet { productName.text = product }
    }
    var quantity: String? {
        didSet { productQty.text = "Qty: \(quantity!)" }
    }
    var price: String? {
        didSet { productPrice.text = "$\(price!)" }
    }
    var img: UIImage? {
        didSet { productImage.image = img }
    }

}

答案 1 :(得分:1)

或者,您可以将ItemSelection内容分解为一个单独的类。

Dictionary(grouping:by:)使您可以将数组变成按指定键组合的字典。下面的代码按商店名称将其分组。

我使用lazy变量,因此在初始化类时不会全部将它们初始化。一切都在需要时初始化。

storeNames是从字典键中检索的。

通过从我从初始数组创建的字典中查找一个值来检索每个商店的元素。

class StoreInfoDataManager {

    struct ItemSelection {
        let storeName: String
        let productName: String
        let productImage: UIImage
        let quantity: String
        let total: String
    }

    lazy var storeDictionary: [String: [ItemSelection]] = {
        return Dictionary(grouping: itemSelections) { $0.storeName }
    }()

    // These are the keys for your sections
    lazy var storeNames: [String] = {
        return Array(storeDictionary.keys).sorted()
    }()

    // This returns an array of items in the store
    func items(for store: String) -> [ItemSelection]? {
        return storeDictionary[store]
    }

    lazy var itemSelections: [ItemSelection] = {
        return [
            ItemSelection(storeName: "Walmart",
                          productName: "Bionicle",
                          productImage: #imageLiteral(resourceName: "Bionicle"),
                          quantity: "4",
                          total: "24"),
            ItemSelection(storeName: "Walmart",
                          productName: "PokeBall",
                          productImage: #imageLiteral(resourceName: "PokeBall"),
                          quantity: "2",
                          total: "30"),
            ItemSelection(storeName: "Target",
                          productName: "Beer",
                          productImage: #imageLiteral(resourceName: "Beer"),
                          quantity: "2",
                          total: "30"),
            ItemSelection(storeName: "Lego Store",
                          productName: "Star Wars Set",
                          productImage: #imageLiteral(resourceName: "Star_Wars_Set"),
                          quantity: "4",
                          total: "256"),
            ItemSelection(storeName: "Lego Store",
                          productName: "Indiana Jones Set",
                          productImage: #imageLiteral(resourceName: "Indiana_Jones_Set"),
                          quantity: "2",
                          total: "88"),
            ItemSelection(storeName: "Amazon",
                          productName: "Coconut Milk",
                          productImage: #imageLiteral(resourceName: "Coconut_Milk"),
                          quantity: "4",
                          total: "20"),
            ItemSelection(storeName: "Amazon",
                          productName: "32 inch Tv",
                          productImage: #imageLiteral(resourceName: "TV"),
                          quantity: "1",
                          total: "156"),
            ItemSelection(storeName: "Amazon",
                          productName: "Amazon Echo",
                          productImage: #imageLiteral(resourceName: "Amazon_Echo"),
                          quantity: "1",
                          total: "80"),
            ItemSelection(storeName: "Amazon",
                          productName: "Grill",
                          productImage: #imageLiteral(resourceName: "Grill"),
                          quantity: "3",
                          total: "90"),
            ItemSelection(storeName: "Amazon",
                          productName: "Coconut Bar",
                          productImage: #imageLiteral(resourceName: "coconuts"),
                          quantity: "4",
                          total: "240")
        ]
    }()
}