带UITableView的UISegmentControl - UITableViewCell布局在更改段时保持不变

问题描述:

在问题标题中提到的场景中,在更改段时,理想情况下UITableView应该重新加载,因此UITableViewCell也应该重新加载。问题是,所有内容都像标签文本一样更新。但是,如果我在一个细分受众群中扩展了细胞的子视图,那么在细分受众群发生变化后,它仍然会展开。
段索引变更功能:带UITableView的UISegmentControl - UITableViewCell布局在更改段时保持不变

@IBAction func segmentOnChange(sender: UISegmentControl) 
{ 
    // Few lines 
    // self.tableMenu.reloadData() 
} 

截图1:

enter image description here

截图2:

enter image description here

所以理想情况下,在截图2中,购物车视图应该已被折叠。

更新:

显示/隐藏视图:

func showHideCartView(sender: UIButton) 
    { 
     let cell = self.tableMenu.cellForRow(at: IndexPath(row: 0, section: Int(sender.accessibilityHint!)!)) as! RestaurantMenuItemCell 
     if sender.tag == 1 
     { 
      // Show cart view 
      cell.buttonArrow.tag = 2 
      cell.viewAddToCart.isHidden = false 
      cell.constraint_Height_viewAddToCart.constant = 50 
      cell.buttonArrow.setImage(UIImage(named: "arrowUp.png"), for: .normal) 
     } 
     else 
     { 
      // Show cart view 
      cell.buttonArrow.tag = 1 
      cell.viewAddToCart.isHidden = true 
      cell.constraint_Height_viewAddToCart.constant = 0 
      cell.buttonArrow.setImage(UIImage(named: "arrowDown.png"), for: .normal) 
     } 

     self.tableMenu.reloadData() 
    } 

的cellForRowAtIndexPath:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "RestaurantMenuItemCell", for: indexPath) as! RestaurantMenuItemCell 
     cell.selectionStyle = .none 
     let menuItem = self.menuItems[indexPath.section] 
     cell.imageViewMenuItem.image = UIImage(named: "[email protected]") 
     cell.labelName.text = menuItem.name 
     cell.labelDescription.text = menuItem.description 
     cell.labelPrice.text = String(format: "$%i", menuItem.price!) 
     cell.buttonArrow.accessibilityHint = String(format: "%i", indexPath.section) 
     cell.buttonArrow.addTarget(self, action: #selector(self.showHideCartView(sender:)), for: .touchUpInside) 

     return cell 
    } 
+0

如何扩展表格单元格?意味着在heightForRowAtIndexPath方法中管理? – iPatel

+0

这应该有一个简单的解决方法..检查你的模型,这决定了一个单元格是否扩展或不..你必须重置它的段更改 –

+0

@iPatel:通过约束。我已经设置estimatedRowHeight = 150和rowHeight = UITableViewAutomaticDimension – Nitish

既然你依靠发送按钮的标签,以确定是否细胞应在展开或折叠状态显示,你需要确保当段改变,该标签的所有单元格buttonArrow也改变为1.

除非发生这种情况,否则单元格将被重用,并且由于buttonArrow的标记设置为2,因此它将显示为展开。

+0

我现在已经采取了处理该模型属性。 – Nitish

这里发生了什么事,当你点击任何行那么这将是扩大基础在showHideCartView方法和之后,当真正的第一个条件n您正在更改保留上一行高度的段索引,因为您正在重复使用单元格因此,当您更改段索引时,必须设置每行的正常高度。

对于采用的indexPath对象像

var selectedIndexPath: NSIndexPath? 

待办事项如果是showHideCartView方法

func showHideCartView(sender: UIButton) { 
    selectedIndexPath = NSIndexPath(row: 0, section: Int(sender.accessibilityHint!)!)) // you can change row and section as per your requirement. 

//// Your other code 
} 

设置selectedIndexPath然后应用以下逻辑每当你正在改变段索引。

@IBAction func segmentOnChange(sender: UISegmentControl) 
{ 
     if indexPath = selectedIndexPath { // check selectedIndexPath is not nil 
      let cell = self.tableMenu.cellForRow(at: indexPath) as! RestaurantMenuItemCell 
      cell.buttonArrow.tag = 1 
      cell.viewAddToCart.isHidden = true 
      cell.constraint_Height_viewAddToCart.constant = 0 
      cell.buttonArrow.setImage(UIImage(named: "arrowDown.png"), for: .normal) 
     } 

    selectedIndexPath = nil // assign nil to selectedIndexPath 
    // Few lines 

    self.tableMenu.reloadData() // Reload your tableview 

} 

正在重用细胞,看你cellForRowAt执行第一行:

let cell = tableView.dequeueReusableCell(withIdentifier: "RestaurantMenuItemCell", for: indexPath) as! RestaurantMenuItemCell 

这意味着,一个的tableView不创建一个新的小区,也不重绘,除非必要的给定indexPath。但是,在代码中,通过在单元的子视图上设置一些高度约束和isHidden标志来展开单元。现在,一旦你在一个新的区段重新加载表格,tableView将使用已经渲染的单元格来尽可能高效地重新加载表格。但是,这意味着尽管您将更改单元格中的数据,除非您明确折叠它,但它会保持展开状态(因为之前您已将约束设置为展开高度)。

当您更改段时,您需要重置展开状态。现在让我们来详细说明一下,因为我相信你目前的解决方案有一个隐藏的bug:

首先,因为我说你离开单元格,万一表格中有很多项目,你滚动通过它们,扩展单元很可能会在表格视图中的某处稍后重用。所以看起来好像有一些随机项目也被扩展了。

因此,我建议您提供一些模型,以记住哪些单元格应该展开,然后使用此模型中的信息更新每个单元格的状态,然后将它们返回到您的cellForRowAt中。该模型可以是一个简单的整数值数组,这些数值可以表示被展开的单元格的索引 - 例如,如果数组中有索引3,则意味着应该展开第3行的单元格。然后,当您将行中的行排列为cellForRowAt,indexPath时,您应该在返回之前在该单元上设置约束条件。这样你可以删除我提到的错误。此外,当你改变数据段时,你可以从数组中删除所有索引来表示不应该扩展任何单元(在调用tableView.reloadData()之前执行)。