【问题标题】:UISegmentControl with UITableView - UITableViewCell layout remains same on changing the segment带有 UITableView 的 UISegmentControl - UITableViewCell 布局在更改段时保持不变
【发布时间】:2017-10-05 20:45:44
【问题描述】:

在问题标题中提到的场景中,在更改段时,理想情况下 UITableView 应该重新加载,因此 UITableViewCell 也应该重新加载。问题是,所有内容都会像标签文本一样更新。但是,如果我在一个段中展开了单元格的子视图,则在段更改后仍保持展开状态。
段索引变化函数:

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

屏幕截图 1:

屏幕截图 2:

理想情况下,在屏幕截图 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: "recommend0@2x.png")
        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
    }

【问题讨论】:

  • 如何扩展表格单元格?表示在 heightForRowAtIndexPath 方法中管理?
  • 这应该很容易解决。检查您的模型,确定单元格是否扩展。您必须在段更改时重置它
  • @iPatel :通过约束。我设置了estimatedRowHeight = 150 和rowHeight = UITableViewAutomaticDimension
  • @MilanNosáľ:用代码更新了我的问题
  • @Nitish 检查我的答案

标签: ios swift uitableview uisegmentedcontrol


【解决方案1】:

由于您依赖发件人按钮的标签来确定单元格应该以展开状态还是折叠状态显示,因此您需要确保当段发生更改时,所有单元格的标签buttonArrow也更改为1 .

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

【讨论】:

  • 我现在已经拿了一个模型属性来处理它。
【解决方案2】:

您正在重用单元格,请参阅cellForRowAt 实现的第一行:

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

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

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

首先,正如我所说的那样,您正在使单元格出列,如果表格中有很多项目并且您正在滚动它们,那么扩展的单元格很有可能会在以后的某个地方被重用在表格视图中。所以看起来也有一些随机项目展开了。

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

【讨论】:

    【解决方案3】:

    这里发生了什么,当您单击任何行时,它将根据 showHideCartView 方法中的第一个条件进行扩展,然后当您更改保持前一行高度的段索引时,因为您正在重用单元格因此您必须在更改段索引时设置每行的正常高度。

    为此,请使用indexPath 的对象

    var selectedIndexPath: NSIndexPath?
    

    然后在showHideCartView方法中设置selectedIndexPath

    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
    }
    

    然后在更改段索引时应用以下逻辑。

    @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
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-30
      • 2016-07-21
      • 1970-01-01
      相关资源
      最近更新 更多