Swift - tableView行高仅在滚动或切换展开/折叠后更新 [英] Swift - tableView Row height updates only after scrolling or toggle expand/collapse

查看:152
本文介绍了Swift - tableView行高仅在滚动或切换展开/折叠后更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 CollapsibleTableView 并根据其修改我要求实现可折叠部分。 以下是它的外观



由于根据UI设计我的部分有一个边框,我选择了部分标题作为我的UI元素,它在折叠和扩展模式下保存数据。



原因:我试过但是无法让它在下面解释的这个模型中运行 -



**在标题标题中包含我的标题元素,并在其单元格中包含每个项目的详细信息。默认情况下,该部分处于折叠状态。当用户点击标题时,切换单元格以显示。正如我所说的,因为有一个边框需要显示给整个部分(tapped header及其单元格),我选择了section header作为我操作的UI元素。这是我的tableView代码 -

  func tableView(tableView:UITableView,numberOfRowsInSection section:Int) - > Int {
return sections.count
}

func tableView(tableView:UITableView,heightForRowAtIndexPath indexPath:NSIndexPath) - > CGFloat {
switch indexPath.row {
case 0:
return sections [indexPath.section] .collapsed! ? 0:(100.0 + heightOfLabel2!)
case 1:
return 0
case 2:
return 0
default:
return 0
}
}


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

让header = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier(header)为! 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
header.titleLabel.text =No_Vouchers.localized()
}
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(名称:voucherDownArrow)
header.setCollapsed(sections [section] .collapsed)

let stringRepresentation = sections [section ] .items.joinWithSeparator(,)

header.benefitDetailText1.tex t = stringRepresentation
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
}
else {
if sections [section] .isNearExpiration == true {
header.benefitAlertImage.hidden = false
header.benefitAlertText.hidden = false
}
else {
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
}
}

如果appLanguageDefault = =nl{
self.totalA mountLabel.text =€\(sections [section] .totalAvailableBudget)
}
else {
self.totalAmountLabel.text =\(sections [section] .totalAvailableBudget)€
}
}

返回标头
}

切换折叠/展开的功能 -
我正在使用部分内动态变化UILabels的高度值,然后使用这些值来扩展边框(使用其layoutconstraint)。

  func toggleSection(header:CollapsibleTableViewHeader,section:Int){
let collapsed =!sections [section ] .collapsed

header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
//切换崩溃
sections [section] .collapsed = collapsed
header.setCollapsed(折叠)

//切换警报标签显示和隐藏
if sections [section] .collapsed == true {
header.cornerRadiusViewBtmConstraint.constant = 0.0
header.cornerRadiusViewTopConstraint.constant = 20.0
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
}
else {

heightOfLabel2 = header.benefitDetailText2.bounds.size.height

if section [ 。]]































header.cornerRadiusViewTopConstraint.constant = 10.0
if let noOfDays = sections [section] .daysUntilExpiration {
if appLanguageDefault ==nl{

header.benefitAlertText。 text =(nog \(noOfDays)dagen geldig)
}
else {
header.benefitAlertText.text =(valable encore \(noOfDays)jour(s))
}
}
}
else {
header.cornerRadiusViewBtmConstraint.constant = -80.0 - heightOfLabel2!
header.cornerRadiusViewTopConstraint.constant = 20.0
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
}
}

//为0中的i调整
tableView.beginUpdates()
部分内行的高度。< sections.count {
tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow:i,inSection:section)],withRowAnimation:.Automatic)
}
tableView.endUpdates()
}

问题:
我需要有几个章节标题在此表视图中,默认情况下,在第一次启动视图时,根据某些条件进行扩展。当我计算标签的高度并使用高度来设置边框的顶部和底部约束时,根据设计显示扩展的部分标题变得很困难。



内容离开边界,因为我的UILabel的高度默认为21。



UPDATE :行高仅在我滚动浏览视图或在崩溃/展开之间切换时更改



问题:
如何计算第一次启动视图时,我的Section标题中出现的UILabels的高度? (这意味着,在我的REST调用完成后,获取数据然后我需要获得UIlabel高度。)



目前,我使用 heightOfLabel2 = header.benefitDetailText2.bounds.size.height



(或)



<有没有更好的方法来实现这个目标?



提前致谢!

解决方案

您可以尝试使用String扩展来计算边界矩形

  extension String {
func height( withConstrainedWidth width:CGFloat,font:UIFont) - > CGFloat {
let constraintRect = CGSize(width:width,height:.greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with:constraintRect,options:.usesLineFragmentOrigin,attributes:[NSFontAttributeName:font],context:零)

返回boundingBox.height
}
}

资料来源:根据UILabel计算尺寸Swift中的字符串


I am using CollapsibleTableView from here and modified it as per my requirement to achieve collapsible sections. Here is how it looks now.

Since there is a border for my section as per the UI design, I had chosen the section header to be my UI element that holds data in both collapsed and expanded modes.

Reason: I tried but couldn't get it working in this model explained below -

** Have my header elements in section header and details of each item in its cell. By default, the section is in collapsed state. When user taps on the header, the cell is toggled to display. As I said, since there is a border that needs to be shown to the whole section (tapped header and its cell), I chose section header to be my UI element of operation. Here is my code for tableView -

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sections.count 
    }

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        switch indexPath.row {
        case 0:
            return sections[indexPath.section].collapsed! ? 0 : (100.0 + heightOfLabel2!)
        case 1:
            return 0
        case 2:
            return 0
        default:
            return 0
        }
    }


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
            header.titleLabel.text = "No_Vouchers".localized()
        }
        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)

            let stringRepresentation = sections[section].items.joinWithSeparator(", ")

            header.benefitDetailText1.text = stringRepresentation
            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
            }
            else {
                if sections[section].isNearExpiration == true {
                    header.benefitAlertImage.hidden = false
                    header.benefitAlertText.hidden = false
                }
                else {
                    header.benefitAlertImage.hidden = true
                    header.benefitAlertText.hidden = true
                }
            }

            if appLanguageDefault == "nl" {
                self.totalAmountLabel.text = "€ \(sections[section].totalAvailableBudget)"
            }
            else {
                self.totalAmountLabel.text = "\(sections[section].totalAvailableBudget) €"
            }
        }

        return header
    }

Function to toggle collapse/expand - I am using height values of the "dynamically changing" UILabels inside the section and then using those values to extend the border (using its layoutconstraint).

func toggleSection(header: CollapsibleTableViewHeader, section: Int) {
        let collapsed = !sections[section].collapsed

        header.benefitAlertImage.hidden = true
        header.benefitAlertText.hidden = true
        // Toggle collapse
        sections[section].collapsed = collapsed
        header.setCollapsed(collapsed)

        // Toggle Alert Labels show and hide
        if sections[section].collapsed == true {
            header.cornerRadiusViewBtmConstraint.constant = 0.0
            header.cornerRadiusViewTopConstraint.constant = 20.0
            header.benefitAlertImage.hidden = true
            header.benefitAlertText.hidden = true
        }
        else {

            heightOfLabel2 = header.benefitDetailText2.bounds.size.height

            if sections[section].isNearExpiration == true {
                header.benefitAlertImage.hidden = false
                header.benefitAlertText.hidden = false
                header.cornerRadiusViewBtmConstraint.constant = -100.0 - heightOfLabel2!
                header.cornerRadiusViewTopConstraint.constant = 10.0
                if let noOfDays = sections[section].daysUntilExpiration {
                    if appLanguageDefault == "nl" {

                        header.benefitAlertText.text = "(nog \(noOfDays) dagen geldig)"
                    }
                    else {
                        header.benefitAlertText.text = "(valable encore \(noOfDays) jour(s))"
                    }
                }                
            }
            else {
                header.cornerRadiusViewBtmConstraint.constant = -80.0 - heightOfLabel2!
                header.cornerRadiusViewTopConstraint.constant = 20.0
                header.benefitAlertImage.hidden = true
                header.benefitAlertText.hidden = true
            }
        }

        // Adjust the height of the rows inside the section
        tableView.beginUpdates()
        for i in 0 ..< sections.count {
            tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: i, inSection: section)], withRowAnimation: .Automatic)
        }
        tableView.endUpdates()
    }

The problem: I need to have, few section headers in this table view to be expanded by default on the first launch of the view, based on some conditions. As I am calculating the height of the labels and using the heights to set for the border's top and bottom constraint, it has become difficult to show the expanded section header as per design.

The content comes out of the border since the height of my UILabel is being taken as 21 by default.

UPDATE: The row height changes only after I scroll through the view or when I toggle between collapse/expand

The Question: How do I calculate the heights of the UILabels present in my Section header by the first time launch of the view? (That means, after my REST call is done, data is fetched and then I need to get the UIlabel height).

Currently, I am using heightOfLabel2 = header.benefitDetailText2.bounds.size.height

(Or)

Is there a better way to achieve this?

Thanks in advance!

解决方案

You can try this for String extension to calculate bounding rect

extension String {
    func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
        let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
        let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)

        return boundingBox.height
    }
}

Source: Figure out size of UILabel based on String in Swift

这篇关于Swift - tableView行高仅在滚动或切换展开/折叠后更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆