Swift - the View Height table is updated only after scrolling or switching to expand / collapse

I use CollapsibleTableView here and modified it according to my requirement to create legible sections. Here's what it looks like now .

Since there is a border for my section in my design, I chose the section title, which will be my user interface element that stores data in both folded and advanced modes.

Reason: I tried, but could not get it to work in this model, described below -

** I have title elements in the section title and details of each element in its cell. By default, the partition is folded. When the user clicks on the title, the cell switches to display. As I said, since there is a border that should be displayed for the entire section (the title of the title and its cells), I selected the title of the section as a user interface control. 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
    }

Collapse / expand mode switching function - I use the heights of the “dynamically changing” UILabels inside the section, and then use these values ​​to expand 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()
    }

: , , . , .

, UILabel .

UPDATE: , collapse/expand

: UILabels, , ? ( , REST , UIlabel).

heightOfLabel2 = header.benefitDetailText2.bounds.size.height

()

?

!

+4
4

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

: UILabel String Swift

-1

, OP. , - . .

:

  • TableViewCells,
  • /

, , .

:

  • TableViewCells
  • Autolayout
  • TableView Automatic Dimension

, ( Autolayout, , .

TableViewCells

. . , , . ( Autolayout ). , , . 1 "" 0 ""

: , , , 0 . .

- , . .

CollapsableCell

. . :

class CollapsableCell: UITableViewCell {

  @IBOutlet weak var titleLabel: UILabel!
  @IBOutlet weak var detailLabel: UILabel!

}

.

, Interface Builder CollapsableCell, .

CollapsableCellViewController

ViewController. TableViewCells:

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


  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "collapsableCell", for: indexPath) as! CollapsableCell
    let item = data[indexPath.row]

    cell.titleLabel?.text = item.title
    cell.detailLabel?.text = item.detail

    return cell
  }

, , . , .

TableView (heightForRowAt:), , ( , ). " ". viewDidLoad :

  override func viewDidLoad() {
    ...
    // settings for dynamic resizing table cells
    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 50
    ...
  }

, 0 , , , , . Dynamic TableViewCells .

/, , . ViewController :

  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    guard let cell = tableView.cellForRow(at: indexPath) as? CollapsableCell else { return }
    let item = data[indexPath.row]

    // update fields
    cell.detailLabel.text = self.isExpanded[indexPath.row] ? item.detail1 : ""

    // update table
    tableView.beginUpdates()
    tableView.endUpdates()

    // toggle hidden status
    isExpanded[indexPath.row] = !isExpanded[indexPath.row]

  }

'var isExpanded = Bool' ViewController, ( TableViewCell).

, , . .

: github. Stackview .

:

  • TableViewCells. , OP , , , .
  • subView - , , . - subView. , , , .
+1

, tableHeaderView toggleSection.

, tableHeaderView , -

// get the headerView
let headerView = self.tableView(self.tableView, viewForHeaderInSection: someSection)

// tell the view that it needs to refresh its layout
headerView?.setNeedsDisplay()

// reload the tableView
tableView.reloadData() 
/* or */ 
// beginUpdates, endUpdates

, , toggleSection(header: CollapsibleTableViewHeader, section: Int)

func toggleSection(header: CollapsibleTableViewHeader, section: Int) {
    ...

    // I'm not sure if this `header` variable is the headerView so I'll just add my code snippet at the bottom
    header.setNeedsDisplay() 


    /* code snippet start */
    // get the headerView
    let headerView = self.tableView(self.tableView, viewForHeaderInSection: someSection)

    // tell the view that it needs to refresh its layout
    headerView?.setNeedsDisplay()
    /* code snippet end */

    // reload the tableView
    // Adjust the height of the rows inside the section
    tableView.beginUpdates()


    // You do not need this
    for i in 0 ..< sections.count {
        tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: i, inSection: section)], withRowAnimation: .Automatic) 
    }
    // You do not need this


    tableView.endUpdates()
}

: TableView headerView/footerView , reloadData() beginUpdates,endUpdates. , , tableView

func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
    return estimatedHeight
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return UITableViewAutomaticDimension
}
0

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

heightOfLabel2 , ( , , , ),

func getHeightForBenefitDetailText2ForIndexPath(indexPath: NSIndexPath)->CGFloat

, ,

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

, , , collapsed true .

, , , .

, . , , .

0
source

Source: https://habr.com/ru/post/1679958/


All Articles