Как вы группируете разделы в табличном представлении? - PullRequest
1 голос
/ 17 октября 2019

Я пытаюсь сгруппировать разделы в 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 ]

1 голос
/ 19 октября 2019

В качестве альтернативы, вы можете разбить ваши вещи 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")
        ]
    }()
}
0 голосов
/ 19 октября 2019

нашел мое решение

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

}

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    let dataSource: ItemDataSource = .init(stores: Items.stores)

    @IBOutlet weak var tableView: UITableView!

    func numberOfSections(in tableView: UITableView) -> Int {
        return dataSource.sections.count
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let store = dataSource.items[section]
        return dataSource.sections[store]?.count ?? 0
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         let storeCell = tableView.dequeueReusableCell(withIdentifier: "StoreCell") as! StoreCell
        let store = dataSource.items[indexPath.section]
        let storeItem = dataSource.sections[store]?[indexPath.row]

        storeCell.product = storeItem?.productName
        storeCell.price = storeItem?.price
        storeCell.quantity = storeItem?.quantity
        storeCell.img = storeItem?.productImage

        return storeCell
    }
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let storeHeader = tableView.dequeueReusableCell(withIdentifier: "StoreHeader") as! StoreHeader
        storeHeader.store = dataSource.items[section]
        return storeHeader
    }
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 45
    }
...