简体   繁体   English

如何使用自定义 header 单元格按字母顺序将 tableview 单元格排列成部分?

[英]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我有来自另一个 ViewController 的代码,该代码通过闭包传递数据以填充 CartVC 中的单元格,该单元格传递数据以成功填充单元格

what I'm trying to do now is have my CartVC arrange the cells into sections by their brand.我现在要做的是让我的 CartVC 按他们的品牌将单元格排列成部分。 But all the data that is passed into the Tableview ends up scrambling the cells into random sections但是传递到 Tableview 的所有数据最终都会将单元格打乱成随机部分

I have been trying to sort the data by brand in my tableview rows alphabetically by section.我一直在尝试按部分按字母顺序在我的 tableview 行中按品牌对数据进行排序。 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.品牌的每个部分都从 AZ 中排序,并在 CartHeaderCell 中使用品牌的完整短语。

My model class for Items has objects: name, brand, price, weight, imageUrl, and category.我的 model class 的Items有对象:名称、品牌、价格、重量、imageUrl 和类别。 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 tableView 通过cell.configure(withItems: cart)显示名称、图像、重量、价格和类别,以填充 CartCells 和 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.我已经尝试了 20 多种不同的方法来完成这项工作,但没有任何帮助。 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.请记住,UITableView 使用其数据源来了解哪些信息应该出现在屏幕上。 It seems like you already have a datasource list, so you just need to sort this list and the UITableViewDataSource will iterate over it.看起来您已经有了一个数据源列表,因此您只需对该列表进行排序,UITableViewDataSource 就会对其进行迭代。 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.以这种方式声明Tray ,结构包含品牌名称和项目。

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 .对数组进行分组,获取键,对它们进行排序,然后将 map 数组放入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
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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