【问题标题】:Swift heightForRowAtIndexPath for views/labels with dynamic heightsSwift heightForRowAtIndexPath 用于具有动态高度的视图/标签
【发布时间】:2017-12-03 07:00:28
【问题描述】:

我有一个名为CollapsibleTableViewHeader 的标题,它的高度是动态的,基于其中包含的UILabelsUIViews

所以,我下面有这个功能-

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

        let header = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier("header") as! CollapsibleTableViewHeader

        switch indexPath.row {
        case 0:
            if sections[indexPath.section].collapsed == true {
                return 0
            }
            else {

              return header.iconsViewHeightConstraint.constant + header.shortDescHeightConstraint.constant + header.validityDateHeightConstraint.constant + header.expiryAlertHeightConstraint.constant
            }

        default:
            return 0
        }

    }

在我的 else 条件下,我需要将标题的高度作为行的高度返回。因此,我将标题中的所有元素相加并返回值(CGFloat)。

高度按预期返回但问题是相同的高度应用于所有单元格。例如如果返回的高度值为 150.0,则相同的 150.0 将应用于所有单元格,无论它们各自的高度如何。

如何获得每个单元格的特定高度? indexPath 是一件很重要的事情,但我不知道如何在这里使用它。

抱歉,如果问题很愚蠢!请帮忙

PS:我已经尝试过automaticDimension,但这无论如何都无济于事,因为我将这些单元格作为折叠/展开单元格。

编辑 1:添加 viewForHeaderInSection 代码

// Header
    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

        let header = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier("header") as! CollapsibleTableViewHeader

        if sections.count == 0 {
            self.tableView.userInteractionEnabled = false
            header.cornerRadiusView.layer.borderWidth = 0.0
            header.benefitAlertImage.hidden = true
            header.benefitAlertText.hidden = true
            header.amountLabel.hidden = true            
        }
        else {
            header.amountLabel.hidden = false
            header.cornerRadiusView.layer.borderWidth = 1.0
            self.tableView.userInteractionEnabled = true
            header.titleLabel.text = sections[section].name
            header.arrowImage.image = UIImage(named: "voucherDownArrow")
            header.setCollapsed(sections[section].collapsed)

            header.benefitDetailText2.text = sections[section].shortDesc
            header.benefitDetailText3.text = sections[section].untilDate

            header.section = section
            header.delegate = self

            if sections[section].collapsed == true {
                header.benefitAlertImage.hidden = true
                header.benefitAlertText.hidden = true
                header.commerceIconsContainerView.hidden = true

                for i in 0..<imagesArray.count {
                    imagesArray[i].image = UIImage(named: "")
                }

            }
            else {
                header.commerceIconsContainerView.hidden = false
                 if sections[section].items.count > 5 {
                    header.iconsViewHeightConstraint.constant = 74.0
                 }

                else {
                    header.iconsViewHeightConstraint.constant = 38.0
                }


                if sections[section].isNearExpiration == true {                 
                    header.benefitAlertImage.hidden = false
                    header.benefitAlertText.hidden = false
                }
                else {                  
                    header.benefitAlertImage.hidden = true
                    header.benefitAlertText.hidden = true
                }
            }
        }

        return header
    }

【问题讨论】:

  • 我其实不明白为什么 UITableViewAutomaticDimension 没有帮助你,因为它看起来像一个经典场景。需要详细说明吗?
  • @OhadM:我不知道为什么。我尝试的第一件事是自动维度,但我总是得到一个静态高度。
  • 所以您没有按应有的方式实现它。请告诉我你试过什么?另外,请提供您需要动态高度的自动布局视图的屏幕截图。
  • 我停止使用 heightForRowAtIndexPath 和 heightForHeaderInSection。在我的 viewDidLoad 中,我添加了estimatedRowHeight 和estimatedHeightForHeader
  • 您不会在恒定高度单元格上仅使用动态估计高度,而您的标题 ISN'T 不是动态的。它是,恒定的。唯一动态的是,在用户点击该标题后,您的单元格会出现在标题中,对吗?

标签: ios swift uitableview uitableviewsectionheader


【解决方案1】:

您需要将在cellForRow 方法中计算的每个单元格的高度存储到一个数组中,然后在heightForRowAtIndexPath 函数中加载

例如:

var heights = [Int]()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as!  Cell
    heights.append(calculationResult)
    return cell
}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return heights[indexPath.row]
}

【讨论】:

  • 所有 UI 元素都在我的部分标题中,而不是自定义单元格:|由于设计问题,我不得不这样做,整个部分都需要边框。
  • 我刚刚尝试了您的建议,但在 viewForHeaderInSection 中附加了高度。如果我错了,请纠正我。我得到一个错误索引超出范围
  • @LohithKorupolu 您使用自定义标题视图?你能把那部分代码贴出来让我看看吗?
  • 我用代码更新了我的问题。 UILabel 的高度因动态内容而异。所以需要计算高度
【解决方案2】:

我不清楚你想做什么。您想根据里面的元素来确定标题的高度应该是多少?如果是这样,那么您使用了错误的功能。你应该使用:

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
    if (isSectionCollapsed) {
        return 0
    } else {
         let sum = subView1.height + subView2.height + subView3.height
         return sum
    }
 }

这就是为什么您的所有行都将其高度设置为 150。如果您试图在某个部分折叠时隐藏行,那么您还需要对您列出的函数中的行进行类似的检查:

override func tableView(_ tableView: UITableView, heightforRowatIndexPath section: Int) -> CGFloat {
    if (isSectionCollapsed) {
        return 0
    } else {
         // return row height for this tableViewCell
    }
 }

编辑: 刚刚看到你的编辑,仍然认为这是同一个问题。该函数正在创建一个标题视图,其高度将通过调用 heightForHeaderInSection 从 ViewController 返回,而不是 heightforRowatIndexPath。

【讨论】:

  • 我想我理解这个问题。正在尝试对代码进行更改。
  • 只需阅读有关部分边框的评论。这包括侧面的边框还是部分的顶部和底部?
  • 所以现在,在 heightForHeaderInSection 中,当我检查每个“部分”的折叠状态时,我得到 index out of range 错误。这是因为节数还没有准备好吗?我很困惑
  • 我在另一个问题上发布了一个完整的工作解决方案。试试看是不是你想要的。
  • 是的,它现在设置为整个单元格,但是很容易获得点击的位置,并且只有在它位于前 x 个像素中时才会做出反应。我过去在这里看到过这样的例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-30
  • 2017-01-17
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 1970-01-01
相关资源
最近更新 更多