如何将当前单元格中的数据与 TableView Swift 4 中的前一个单元格进行比较?

Posted

技术标签:

【中文标题】如何将当前单元格中的数据与 TableView Swift 4 中的前一个单元格进行比较?【英文标题】:How to compare the data from current cell with its previous cell inside TableView Swift 4? 【发布时间】:2018-02-24 08:38:51 【问题描述】:

我有一个 JSON,看起来像这样:

"product": [
    
        "product_id": 471,
        "info": "123456",
    ,
    
        "product_id": 471,
        "info": "356697456",
    ,
    
        "product_id": 472,
        "info": "1432",
    ,
    
        "product_id": 473,
        "info": "4321",
    ,
]

我想将我的 TableView 设置为如下图所示:

我想要的是:

    如果 TableView 中的第一个单元格我希望显示产品 1(红色)。

    如果第二个单元格的 product_id 与前一个单元格的 product_id 相同,则产品 1 不再显示,它会消失。

    由于第三个单元格的product_id与前一个单元格(第二个单元格)不同,所以会显示红色标签 Product 2。

    同样转到Product 3TableView 中的单元格的其余部分

我已经尝试过的:

为了实现这一点,我需要在cellAtRowdelegate中获取indexPath,所以我将每个单元格的product_id与前一个进行比较,然后控制里面的逻辑。

这是我的代码

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

        let thisIndexPath = indexPath.row
        if thisIndexPath - 1 > -1 

            let previousProductId = self.productItem[thisIndexPath - 1].productId
            let thisProductId = self.productItem[thisIndexPath].productId

            if  previousProductId == thisProductId 

                cell.productLabel.isHidden = true
                cell.productHeight.constant = 0
                cell.productnameTopContraint.constant = 0
                cell.productnameBottomContraints.constant = 0
            else 
                cell.productnameLabel.isHidden = false

            
        else
            cell.productnameLabel.isHidden = false
        

        cell.item = selfProductItem[indexPath.row]
        return cell
    

但现在的问题是:

-- TableView 首次启动时,UI 显示如上所示,但是当我开始滚动时,所有单元格的 Product 标签(红色)都消失了,尽管product_id 与前一个单元格的product_id 不同。

-- 当我滚动回第一个单元格时,产品标签(红色)也消失了。这意味着 UI 仅在屏幕第一次启动时正确,这不是持久的。

所以我的问题是:

    比较当前单元格和前一个单元格的数据的正确方法是什么?

    cellForRowAt委托方法里面做比较对吗?如果不是,我应该在哪里做呢?

【问题讨论】:

看起来您正在使用 1 个部分,尝试为每个 product_id 创建部分,并将行添加到相同产品的部分。 @TomaszCzyżak 嘿兄弟,因为product 1product_2 也会出现在底部 尝试在 else 部分也设置高度限制 @TomaszCzyżak 数据不是分段的,是产品 1,2,3,1,2,1 ,顺序是完全随机的 else 部分:if previousProductId == thisProductId 和:if thisIndexPath - 1 > -1 【参考方案1】:

我认为要解决您的问题,您应该考虑如何存储 JSON 数据。

您可以首先创建一个名为“Product”的struct,它将存储产品信息,然后将其设置为Equatable,您可以添加一个函数来比较产品ID:

/// Structure Of A Product
struct Product: Equatable

  var productID: Int
  var productInfo: Int

  static func == (lhs: Product, rhs: Product) -> Bool 
    return lhs.productID == rhs.productID
  

现在要使用这个结构,您可以创建一个数组变量来存储您的产品:

//Array To Store Array Of Product
var products = [Product]()

在此示例中,我只是手动输入产品信息,但您应该以更好的方式进行处理。但是,它确实说明了您可以“开始”处理此问题的一种方式:

   override func viewDidLoad() 
    super.viewDidLoad()

    //1. Create Products
    let productOne = Product(productID: 471, productInfo: 123456)
    let productTwo = Product(productID: 471, productInfo: 356697456)
    let productThree = Product(productID: 472, productInfo: 1432)
    let productFour = Product(productID: 473, productInfo: 4321)

    //2. Add Them To The Products Array
    addUnique(productOne)
    addUnique(productTwo)
    addUnique(productThree)
    addUnique(productFour)



/// Checks That A Product Doesn't Exist
///
/// - Parameter product: Product
func addUnique(_ product: Product) 
    if !products.contains(product) 
        products.append(product)
    

在第 1 步中,我们手动创建产品。

在第 2 步中,我们调用 addUnique(_ product) 函数,它只允许存储唯一的产品。

在确保没有重复的 ProductID 之后,您应该可以轻松设置自己喜欢的格式:

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyCell
    cell.productLabel.text = products[indexPath.row].productID
    cell.productnameLabel.text = products[indexPath.row].productInfo

当然,您需要修复标签等的任何颜色。

【讨论】:

这应该被接受,因为它符合逻辑 - 将数据源与演示者分开,非常棒。【参考方案2】:

我试过了,效果很好。我为你制作了一个虚拟数组。请检查以下内容

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource 

@IBOutlet weak var tblProduct: UITableView!

var arrProduct = NSMutableArray()
var arrForSection = NSMutableArray()
var arrForProductId = NSMutableArray()

override func viewDidLoad()

    super.viewDidLoad()

    let dict = NSMutableDictionary()
    dict.setValue("471", forKey: "product_id")
    dict.setValue("123456", forKey: "info")
    arrProduct.add(dict)

    let dict1 = NSMutableDictionary()
    dict1.setValue("471", forKey: "product_id")
    dict1.setValue("356697456", forKey: "info")
    arrProduct.add(dict1)

    let dict2 = NSMutableDictionary()
    dict2.setValue("472", forKey: "product_id")
    dict2.setValue("1432", forKey: "info")
    arrProduct.add(dict2)

    let dict3 = NSMutableDictionary()
    dict3.setValue("472", forKey: "product_id")
    dict3.setValue("4321", forKey: "info")
    arrProduct.add(dict3)

    print(arrProduct)

    self.createSection()


//MARK:
//MARK: Create section
func createSection()

    arrForSection.removeAllObjects()
    let arrtemp = NSMutableArray()

    arrtemp.addObjects(from: (self.arrProduct as NSArray) as! [Any])

    for i in 0 ..< arrtemp.count
    
        let dict = self.arrProduct[i] as! NSMutableDictionary
        let strProductId = (dict["product_id"] as? String)!

        if(!arrForProductId .contains(strProductId))
        
            arrForProductId.add(strProductId)
        
    

    for j in 0 ..< arrForProductId.count
    
        let strTempDate:String = arrForProductId .object(at: j) as! String
        let arr1 = NSMutableArray()

        for i in 0 ..< arrtemp.count
        
            let dict = arrtemp .object(at: i) as! NSMutableDictionary
            let strProductId = (dict["product_id"] as? String)!
            if(strProductId == strTempDate)
            
                arr1.add(dict)
            
        
        arrForSection.add(arr1)
    

    self.tblProduct.reloadData()


//MARK:
//MARK: TableView Delegate
func numberOfSections(in tableView: UITableView) -> Int 

    return self.arrForSection.count


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

    return (((arrForSection .object(at: section)) as! NSMutableArray).count)


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

    let cell:UITableViewCell = self.tblProduct.dequeueReusableCell(withIdentifier: "cell")!

    let dictData = ((arrForSection .object(at: indexPath.section)) as! NSMutableArray).object(at: indexPath.row) as! NSDictionary

    cell.textLabel?.text = dictData["info"] as? String

    return cell


func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?

    return arrForProductId[section] as? String


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)





override func didReceiveMemoryWarning()

    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.



结果见附件

希望对你有帮助!

【讨论】:

【参考方案3】:

我认为在这种情况下,您可以将表格视图的单元格划分为多个部分,并将标题(产品名称)分配给每个部分。请回复official documentation了解更多信息。

【讨论】:

【参考方案4】:

尝试在其他部分设置高度限制。 else 部分:if previousProductId == thisProductId 和:if thisIndexPath - 1 &gt; -1

【讨论】:

以上是关于如何将当前单元格中的数据与 TableView Swift 4 中的前一个单元格进行比较?的主要内容,如果未能解决你的问题,请参考以下文章

如何更新 TableView 静态单元格中的数据?

如何通过单击单元格中的按钮来删除 tableView 中的单元格?使用核心数据

如何在加载了 JSON API 数据的 tableview 单元格中保存复选标记属性?

如何使tableView中单元格中的图像一致显示?

TableView 单元格中的 MVVM

多个tableView单元格中的多个collectionView