3

I have a UITableView inside a UIViewController as part of the view. I'm trying to autoresize the table cells based on the length of the text. it doesn't set the text of the textview and the cell ends up at standard height for the idCellTextView-cell. I've searched around and am trying to use pinning in auto layout from the textview inside the cell relative to the content view and the code as shown below. :

tableView.estimatedRowHeight = 70
tableView.rowHeight = UITableViewAutomaticDimension

The rest of the view controller thats relevant to the problem is shown under:

class ExperimentViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextViewDelegate {
var expId: String = ""
let experimentDescription: String = ""
var cellDescriptors: NSMutableArray!
var visibleRowsPerSection = [[Int]]()


let notificationCenter = NotificationCenter.default

override func viewDidLoad() {
    super.viewDidLoad()


    //TABLE CELLS
    loadCellDescriptors()
    tableView.tableFooterView = UIView()
    tableView.layoutMargins = UIEdgeInsets.zero
    tableView.separatorInset = UIEdgeInsets.zero
    tableView.delegate = self
    tableView.dataSource = self
    tableView.isHidden = true
    tableView.estimatedRowHeight = 70
    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")
    tableView.register(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "idCellNormal")
    tableView.register(UINib(nibName: "HintCell", bundle: nil), forCellReuseIdentifier: "idCellTextView")


    //ADD VIEWS
    baseView.addSubview(backgroundImage)
    baseView.addSubview(foregroundImage)
    baseView.addSubview(nameLabel)
    baseView.addSubview(segmentedController)
    baseView.addSubview(descriptionText)
    baseView.addSubview(hint)
    baseView.addSubview(tableView)

}



/*
 Get property list for the different cells we want to have in the hint table
 */
func loadCellDescriptors() {
    if let path = Bundle.main.path(forResource: "CellDescriptor", ofType: "plist") {
        cellDescriptors = NSMutableArray(contentsOfFile: path)
        getIndicesOfVisibleRows()
        tableView.reloadData()
    }
}

/*
 Returns number of rows in a given section
 */
func tableView(_ tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
    return visibleRowsPerSection[section].count
}

/*
 Returns number of sections in table
 */
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    /*if cellDescriptors != nil {
        return cellDescriptors.count
    }
    else {
        return 0
    }*/
    print(items.count)
    return 3
}

/*
 Sets up the cell contents
 */
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let currentCellDescriptor = getCellDescriptorForIndexPath(indexPath)
    let cell = tableView.dequeueReusableCell(withIdentifier: currentCellDescriptor["cellIdentifier"] as! String , for: indexPath) as! CustomCell

    if currentCellDescriptor["cellIdentifier"] as! String == "idCellNormal" {
        print("1")
        if currentCellDescriptor["primaryTitle"] != nil {
            cell.labelOfRow.text = "Hintet er"
            cell.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
        }
    } else if currentCellDescriptor["cellIdentifier"] as! String == "idCellTextView" {

        cell.textView.delegate = self
        cell.textView.isEditable = false
        cell.textView.isSelectable = false
        cell.textView.isScrollEnabled = true
        cell.textView.text = "orem Ipsum er rett og slett dummytekst fra og for trykkeindustrien. Lorem Ipsum har vært bransjens standard for dummytekst helt siden 1500-tallet, da en ukjent boktrykker stokket en mengde bokstaver for å lage et prøveeksemplar av en bok. Lorem Ipsum har tålt tidens tann usedvanlig godt, og har i tillegg til å bestå gjennom fem århundrer også tålt spranget over til elektronisk typografi uten vesentlige endringer. Lorem Ipsum ble gjort allment kjent i 1960-årene ved lanseringen av Letraset-ark med avsnitt fra Lorem Ipsum, og senere med sideombrekkingsprogrammet Aldus PageMaker som tok i bruk nettopp Lorem Ipsum for dummytekst.orem Ipsum er rett og slett dummytekst fra og f"
    }
    cell.layoutMargins = UIEdgeInsets.zero

    return cell
}

/*
 Handles row selections
 Finds the index of the cell that was selected, checks if it is/can be expanded and animates in the additional rows
 */
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let indexOfTappedRow = visibleRowsPerSection[indexPath.section][indexPath.row]
    let cellDescriptor = cellDescriptors[indexPath.section] as! NSMutableArray
    let cell = (cellDescriptors[indexPath.section] as! NSMutableArray)[indexOfTappedRow]
    var shouldExpandAndShowSubRows: Bool = false

    //Checks if cell is expandable, if it is we check if cell isn't already expanded. If it isn't we can expand the cell
    if (cell as AnyObject)["isExpandable"] as! Bool == true {
        shouldExpandAndShowSubRows = false
        if (cell as AnyObject)["isExpanded"] as! Bool == false {
            shouldExpandAndShowSubRows = true
        }
    }

    (cell as AnyObject).setValue(shouldExpandAndShowSubRows, forKey: "isExpanded")

    //Makes the cells inside the specific section visible
    for i in (indexOfTappedRow + 1)...(indexOfTappedRow + ((cell as AnyObject)["additionalRows"] as! Int)) {
        (cellDescriptor[i] as AnyObject).setValue(shouldExpandAndShowSubRows, forKey: "isVisible")
    }

    //Update the overview of the currently visible rows
    getIndicesOfVisibleRows()
    //Reload the sections to see the changes
    tableView.reloadSections(NSIndexSet(index: indexPath.section) as IndexSet, with: UITableViewRowAnimation.fade)
}

/*
 Get overview of the rows that are currently visible
 */
func getIndicesOfVisibleRows() {
    visibleRowsPerSection.removeAll()

    for currentSectionCells in cellDescriptors.objectEnumerator().allObjects as! [[[String:AnyObject]]] {
        var visibleRows = [Int]()

        for row in 0...((currentSectionCells).count - 1) {
            if currentSectionCells[row]["isVisible"] as! Bool == true {
                visibleRows.append(row)
            }
        }

        visibleRowsPerSection.append(visibleRows)
    }
}

/*
 Get cell descriptor from file for specific cell
 */
func getCellDescriptorForIndexPath(_ indexPath: IndexPath) -> [String: AnyObject] {
    let indexOfVisibleRow = visibleRowsPerSection[indexPath.section][indexPath.row]
    let cellDescriptor = (cellDescriptors[indexPath.section] as! NSMutableArray)[indexOfVisibleRow] as! [String: AnyObject]
    return cellDescriptor
}
}
Krunal
  • 77,632
  • 48
  • 245
  • 261
André
  • 143
  • 1
  • 14

4 Answers4

1

Try this:

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

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

Here Example

iParesh
  • 2,338
  • 1
  • 18
  • 30
0

Try this -

Make sure you have add constraint properly in table view cell first.

Then Set these two properties of UILable from Attributes inspector section of storyboard:

1 - lines to 0

2 - Line break to word wrap

Note - Do not fix the height of UILable.

For TextView -

you need to disable scrolling. it will work.

Prema Janoti
  • 836
  • 5
  • 18
0

You have to set numberOfLines to 0 to allow the UILabel inside the cell grows

Bruno Bieri
  • 9,724
  • 11
  • 63
  • 92
0

I suggest to use AutoLayout instead of auto resizing. It's easy and better to design UI elements. Following steps will help you, how you can design auto resizing cell using AutoLayout.

To set automatic dimension for row height & estimated row height, ensure following steps to make, auto dimension effective for cell/row height layout.

  • Assign and implement dataSource and delegate
  • Assign UITableViewAutomaticDimension to rowHeight & estimatedRowHeight
  • Implement delegate/dataSource methods (i.e. heightForRowAt and return a value UITableViewAutomaticDimension to it)

-

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Don't forget to set dataSource and delegate for table
    table.dataSource = self
    table.delegate = self

   // Set automatic dimensions for row height
    // Swift 4.2 onwards
    table.rowHeight = UITableView.automaticDimension
    table.estimatedRowHeight = UITableView.automaticDimension


    // Swift 4.1 and below
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension

}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // Swift 4.2 onwards
    return UITableView.automaticDimension

    // Swift 4.1 and below
    return UITableViewAutomaticDimension
}

For label instance in UITableviewCell

  • Set number of lines = 0 (& line break mode = truncate tail)
  • Set all constraints (top, bottom, right left) with respect to its superview/ cell container.
  • Optional: Set minimum height for label, if you want minimum vertical area covered by label, even if there is no data for label/text.

enter image description here

Krunal
  • 77,632
  • 48
  • 245
  • 261