如何将项目排列成表格视图中的部分?

Posted

技术标签:

【中文标题】如何将项目排列成表格视图中的部分?【英文标题】:How to arrange items into sections in a tableview? 【发布时间】:2019-11-14 09:13:50 【问题描述】:

我能说的最简单的方法是如何在 CartVC 中按其品牌将单元格排列成部分

因为我所做的只是在购物车中按其品牌组织单元格,这与将数据从 HomeVC 传递到购物车后我们手机中联系人的排列方式类似

代码确实成功地将数据从 HomeVC 传递到 CartVC,但单元格仍然没有按品牌名称排列

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 CartVC when ATC Btn is pressed in each cell
        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!

    var setUp: [Items] = []
    var groupedItems: [String: [Items]] = [:]
    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 1
    

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

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


        let brand = brands[indexPath.section]
        let itemToDisplay = groupedItems[brand]![indexPath.row]

        // code that currently transfers data to the cells when ATC is pressed
        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

        let headerTitle = brands[section]

        return cartHeader
    

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

【问题讨论】:

很少有人会花一分钟以上阅读别人的问题。所以你可能想缩短你的问题。 你是对的,会的 你能在一行中写出具体的问题吗? 我的问题是如何在 CartVC 中按其品牌将单元格排列成部分 【参考方案1】:

无法在此处跟踪您的所有代码,但假设您有一个数组 items,它是一个 Item 数组,其中每个 item 都有一个 .brand: String 属性

在进入视图控制器时,设置要显示的数据:

var items: [Item] //populated in segue
var groupedItems: [String: [Items]] =[:]
var brands: [String] = []

override viewDidLoad() 
  super.viewDidLoad()
  // any other stuff
  groupedItems = Dictionary(grouping: items, by: $0.brand)
  brands = groupedItems.map$0.key.sorted()

使用brands 数组来形成您的自定义标题,然后在cellForRowAt 中根据 indexPath 参数检索您需要显示的项目


func numberOfSections(in tableView: UITableView) -> Int     
  return brands.count


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    let brand = brands[section]
    return groupedItems[brand].count


func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
   let headerTitle = brands[section]
   // create and configure the header view
   // the headerTitle contains the 'brand' string for the header


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

   // retrieve the relevant item to display...
   // 1. use the section to retrieve the specific brand name string for the section from the brands array
   // 2. then use that that to retrieve the appropriate items array from the dictionary
   // 3. the use indexPath.row to retrieve the specific item for the cell

   let brand = brands[indexPath.section]
   let itemToDisplay = grouped[brand]![indexPath.row]

   //configure cell with itemToDisplay...

   return cell

【讨论】:

我会把这个放在我的 HomeVC 还是 CartVC 中?以及我将如何设置它以将我的品牌放在标题中?,抱歉@flanker 我刚下班,我现在全神贯注于迟到的回应 是否需要 TrayDataSource、TrayItem 类及其扩展?还是我会完全消除它们? 因为我要做的只是在购物车中按其品牌组织单元格,类似于我们手机中联系人的排列方式一旦数据从 HomeVC 传递到购物车 @Evelyn 不用担心时间问题。这进入了 CartVC,并旨在显示按其.brand 属性分组的卡片内容。我得检查一下那些其他物品的用途 如果所有这些类的用途是让按品牌分组的项目准备好用于 tableView,那么它们可以被删除。您必须更改其他 tableview 函数以将 brands 数组用于节标题,将 groupedItems 字典用于单元格信息。但这一切都应该比以前简单得多。 我真正需要在我的购物车中完成这项工作的唯一类是 Tray 类。另外两个 (TrayItem 和 TrayDataSource) 是我用来使其组织用于测试目的的。我会相应地更新我的问题,让它看起来更干净【参考方案2】:

可以简单的实现

    为购物车中的所有产品创建一个所有独特品牌的列表(产品数组):创建一个 <SET> 并遍历所有选择的产品并将其品牌添加到 <SET>

    对于<SET>中的每个品牌,创建一个过滤掉该品牌所有产品的谓词,您也可以为它使用Filter。将结果存储在单独的品牌数组中,一旦处理完成,将TableView中的列数设置为过滤后创建的数组数,并将每个部分中的行数设置为每个数组的计数

希望这会有所帮助!

【讨论】:

我对如何做到这一点有点困惑,你能更具体一点吗?

以上是关于如何将项目排列成表格视图中的部分?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3 - 重新排列并保留表格视图中的单元格

如何根据优先级重新排列列表视图中的项目?

在运行时重新排列表格视图中的单元格

将单元格移动到表格视图中的新部分

如何将带有字符串@“XYZ”的部分设置为表格视图中的第一部分

如何将 NSArray 拆分为按字母顺序排列的部分以与索引表视图一起使用