简体   繁体   中英

how to arrange tableview cells into sections alphabetically with custom header cell?

I have code from another ViewController that passes data through a closure to populate the cells in the CartVC which passes data to populate the cells successful

what I'm trying to do now is have my CartVC arrange the cells into sections by their brand. But all the data that is passed into the Tableview ends up scrambling the cells into random sections

I have been trying to sort the data by brand in my tableview rows alphabetically by section. I've managed to create the sections and an index, but can't figure out how to get the brands to sort; every section of brand is sorted from AZ with the full phrase of the brand in the CartHeaderCell.

My model class for Items has objects: name, brand, price, weight, imageUrl, and category. The tableView displays name, image, weight, price and category through cell.configure(withItems: cart) to populate the CartCells and the brand being in the CartHeaderCells

import UIKit

class CartViewController: UIViewController {

    var items: Items!

    var setUp: [Tray] = []
    var groupedItems: [String: [Tray]] = [:]
    var brands: [String] = []

    @IBOutlet weak var cartTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        cartTableView.dataSource = self
        cartTableView.delegate = self

        groupedItems = Dictionary(grouping: setUp, by: {$0.brand})
        brands = groupedItems.map{$0.key}.sorted()
    }

}

extension CartViewController: UITableViewDataSource, UITableViewDelegate {

    func numberOfSections(in tableView: UITableView) -> Int {
        return Tray.currentCart.cartItems.count
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return Tray.currentCart.cartItems[section].count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CartCell", for: indexPath) as! CartCell

        let itemToDisplay = groupedItems[brands[indexPath.section]]![indexPath.row] 
        let cart = Tray.currentCart.cartItems[indexPath.row]
        cell.configure(withItems: cart)

        return cell
    }

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

        cartHeader.storeName.text = "Brand: \(Tray.currentCart.cartItems[section].brand)"
        return cartHeader
    }

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

}

class Tray {
    static let currentCart = Tray()
    var cartItems = [Items]()
    var cart: Items!
}

Ive tried over 20 different ways if not more to make this work and nothing has helped. Any suggestions would be greatly appreciated. Thanks in advance!

Keep in mind that UITableView uses its datasource to know which information should appear on the screen. It seems like you already have a datasource list, so you just need to sort this list and the UITableViewDataSource will iterate over it. Do something like this:


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CartCell", for: indexPath) as! CartCell

        let brandSource = Tray.currentCart.cartItems[indexPath.section].sorted{$0.brand.lowercased() < $1.brand.lowercased()} 
        let cart = brandSource[indexPath.row]
        cell.configure(withItems: cart)

        return cell
}

It's a good thing to improve your objects structures a little bit better or soon you will lose control of your app.

Declare Tray this way, the struct contains the brand name and the items.

struct Tray {
    let brand : String
    let cartItems : [Items]
}

Declare the datasource array

var trays = [Tray]()

Group the array, get the keys, sort them and map the array to an array of Tray .

let groupedItems = Dictionary(grouping: setUp, by: {$0.brand})
let keys = groupedItems.keys.sorted()
trays = keys.map{Tray(brand: $0, cartItems: groupedItems[$0]!)}

And change the data source and delegate methods to

extension CartViewController: UITableViewDataSource, UITableViewDelegate {

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

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CartCell", for: indexPath) as! CartCell

        let cart = trays[indexPath.section].cartItems[indexPath.row] 
        cell.configure(withItems: cart)    
        return cell
    }

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

        cartHeader.storeName.text = "Brand: \(trays[section].brand)"
        return cartHeader
    }

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM