如何将当前单元格中的数据与 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 3
和TableView
中的单元格的其余部分
我已经尝试过的:
为了实现这一点,我需要在cellAtRow
delegate中获取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 1
或product_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 > -1
。
【讨论】:
以上是关于如何将当前单元格中的数据与 TableView Swift 4 中的前一个单元格进行比较?的主要内容,如果未能解决你的问题,请参考以下文章
如何通过单击单元格中的按钮来删除 tableView 中的单元格?使用核心数据