如何使用自定义标题将单元格排列成节?

时间:2019-11-16 09:41:11

标签: ios arrays swift uitableview uitableviewsectionheader

如何使用自定义标题按节排列单元格

我已设置代码以按品牌排列CartVC中的单元(将品牌放置在CartHeaderCell中)。当数据从HomeVC传递到CartVC时,我无法从我在CartVC中创建的代码中按品牌将单元格按节排列。 (当前代码将数据从HomeVC传递到CartVC,而没有将单元格分成几部分)

将数据传递到购物车后,如何在CartVC中按品牌排列这些部分

更新

现在,CartViewController Extension中的代码将单元格划分为多个部分,然后按品牌将其传递到单元格中,但是将所有单元格加扰为随机部分,或者在单元格中为品牌创建一个新部分,和/或在按下CartBtn时使模拟器崩溃,或者在多个部分中显示相同的项目/单元格

image

extension HomeController: UITableViewDelegate, UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return itemSetup.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "HomeCell") as? HomeCell else { return UITableViewCell() }

        let item = itemSetup[indexPath.row]
        cell.configure(withItems: item)

        // passes data to the Cart Cells in the CartVC when ATC Btn is pressed in each HomeCell
        cell.addActionHandler = { (option: Int) in
            print("Option selected = \(option)")
            Tray.currentCart.cartItems.append(item)
            item.selectedOption = option
        }

        return cell
    }
}

import UIKit

class CartViewController: UIViewController {

    var items: Items!

    // arranges cells into sections
    var tray: [Tray] = []
    var sortedBrandsByName: [String] = []
    var sections: [[Tray]] = [[]]

    @IBOutlet weak var cartTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // arranges cells into sections
        let brandNames = tray.map { $0. titleBrandName }
        let uniqueBrandNames = Array(Set(brandNames))           
        let sortedBrandNames = uniqueBrandNames.sorted()
        let sections: [[Tray]] = sortedBrandNames.map { firstBrandNames in
            return tray
                .filter { $0. titleBrandName == firstBrandNames } 
                .sorted { $0.cart.brand < $1.cart.brand } // sort them
        }

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

    }
}

extension CartViewController: UITableViewDataSource, UITableViewDelegate {

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        //allows data passed from the HomeVC populate the CartCells
        return Tray.currentCart.cartItems[section].count
    }

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

        // **Active code** that allows data passed from the HomeVC populate the CartCells
        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 = Tray.currentCart.cartItems[section].brand
        return cartHeader
    }

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

class CartHeaderCell: UITableViewCell {

    @IBOutlet weak var brandName: UILabel!

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

class CartCell: UITableViewCell {

    @IBOutlet weak var lblMealName: UILabel!
    @IBOutlet weak var imageUrl: UIImageView!
    @IBOutlet weak var lblSubTotal: UILabel!
    @IBOutlet weak var lblQty: UILabel!

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

    // allows the data to be passed into the cart cells

    func configure(withItems items: Items) {
        imageUrl.sd_setImage(with: URL(string: items.imageUrl))
        lblQty.text = "\(items.count)"
        let formatter = NumberFormatter()
        formatter.maximumFractionDigits = 2
        formatter.numberStyle = .decimal
        if items.selectedOption == 1 {
            lblSubTotal.text = "$\(formatter.string(for: items.price1 * Float(items.count))!)"
            lblMealName.text = "\(items.name) ● \(items.weight1)"
        } else if items.selectedOption == 2 {
            lblSubTotal.text = "$\(formatter.string(for: items.price2 * Float(items.count))!)"
            lblMealName.text = "\(items.name) ● \(items.weight2)"
        } else if items.selectedOption == 3 {
            lblSubTotal.text = "$\(formatter.string(for: items.price3 * Float(items.count))!)"
            lblMealName.text = "\(items.name) ● \(items.weight3)"
        }
    } 
}

// allows the code that is passed to the CartVC when an item is passed from the HomeVC to the CartVC
class Tray {
    static let currentCart = Tray()
    var cartItems = [Items]()
    var cart: Items!
    var sectionTitle: String!
}

extension Tray {
    var titleBrandName: String {
        return String(self.cart.brand[self.cart.brand.startIndex]).uppercased()
    }
}

1 个答案:

答案 0 :(得分:1)

问题是您实际上并未保存正在执行的排序。即使您曾经在UITableViewDataSource方法中查看数据的代码的另一部分。

第一个问题:您实际上并没有保存数据。 确保创建CartViewController的函数实际上在tray之前传入viewDidLoad:

在这一部分:

import UIKit

class CartViewController: UIViewController {

    var items: Items!

    // arranges cells into sections
    var tray: [Tray] = []
    var sortedBrandsByName: [String] = []
    var sections: [[Tray]] = [[]]

    @IBOutlet weak var cartTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // arranges cells into sections
        let brandNames = tray.map { $0. titleBrandName }
        let uniqueBrandNames = Array(Set(brandNames))           
        let sortedBrandNames = uniqueBrandNames.sorted()
        let sections: [[Tray]] = sortedBrandNames.map { firstBrandNames in
            return tray
                .filter { $0. titleBrandName == firstBrandNames } 
                .sorted { $0.cart.brand < $1.cart.brand } // sort them
        }

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

    }
}

您的viewDidLoad创建sortedBrandNamessections的本地版本。 删除lets,然后尝试以下操作:

override func viewDidLoad() {
    super.viewDidLoad()

    // arranges cells into sections
    let brandNames = tray.map { $0. titleBrandName }
    let uniqueBrandNames = Array(Set(brandNames)) 

    // MY CHANGES ARE BELOW (remove let)      
    sortedBrandNames = uniqueBrandNames.sorted()
    sections: [[Tray]] = sortedBrandNames.map { firstBrandNames in
        return tray
            .filter { $0. titleBrandName == firstBrandNames } 
            .sorted { $0.cart.brand < $1.cart.brand } // sort them
    }

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

}

一般反馈..您应该使用THESE来填充表格视图,而不要使用静态Tray.currentTray。将数据保存在可以从代码库中任何位置读取/写入的值上确实很糟糕。

第二..您正在从UITableViewDataSource方法的不同数据集中读取数据...

说我们现在确实设法保存了已排序的数据...当您执行Tray.currentCart时,您实际上并没有查看刚刚排序的数据(即self.sections),这是没有做的您可以更改Tray.currentCart中的数据(再次很糟糕,不要制作像这样或单例的静态内容,这样超级容易引入错误)

   func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        //allows data passed from the HomeVC populate the CartCells
        return Tray.currentCart.cartItems[section].count
    }

相反,请尝试以下操作:

extension CartViewController: UITableViewDataSource, UITableViewDelegate {

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

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

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

        let cart = self.sections[indexPath.section][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 = self.sections[section].brand
        return cartHeader
    }

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

这样,您可以查看刚刚在viewDidLoad中排序的数据。 (请注意,我假设您的排序逻辑正常工作)