Variable height UITableViewCell expands after scrolling to end of list and rotating
Asked Answered
H

1

8

UPDATE

I know what is causing this strange breaking of layout. It is the setting of an Accessory (UITableViewCellAccessory). If I stop specifying an accessory the layout does not break. I have not added this as the answer because an answer would need a solution that gives me an accessory without breaking layout

Most of the issues I see people having with custom cells of dynamic height are that they do not have the correct height until they are rotated. However I see the opposite: All cells are the height valid for their dynamic content. Scrolling up and down does not break this. However if I scroll to the bottom of the list, then rotate the device, then rotate back one row will become between 0.5 and 1.5 times the height of the screen.

A further rotation or a further scroll will put the rows back to the expect height. I have included a couple of before and after screenshots

Table before scroll

Table after scroll and rotate

The UITableView is defines as follows

this.rootChildrenTable = new UITableView()
            {
                TranslatesAutoresizingMaskIntoConstraints = false,
                AccessibilityIdentifier = "rootChildrenTable",
                RowHeight = UITableView.AutomaticDimension,
                EstimatedRowHeight = 44.0f,
                BackgroundColor = UIColor.GroupTableViewBackgroundColor,
                TableFooterView = new UIView(),
                TableHeaderView = this.searchBar,
                KeyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag
            };

Note the usual suspects are set RowHeight and EstimatedRowHeight. As soon as I remove the Lines = 0 from the label, making the rows all the same height, the issue goes away.

Any idea what else I should be looking at?

Hollow answered 13/9, 2016 at 9:11 Comment(7)
I think you can observe the rotation and call beginUpdate and endUpdate to update the cell heightPidgin
I might be able to do that but I have lots of dynamic height tables and don't normally get this so surely there must be a "proper" solution for this rather than a "not sure what's going on so let's force and cell height update"Hollow
Are you using a UITableViewController or a UITableView inside a UIViewController?Amenable
Can you show how the cells are set up? Are you using autolayout constraints?Branks
How do you set text to your cell. Are you doing it in "cellForRowAt indexPath" or you doing it in "willDisplay cell". I notice that if you set text in "willDisplay cell" the dynamic cell height will not work correctly.Kilgore
@Amenable I have a UITableView inside a UIViewControllerHollow
@Sven-MichaelStübe I have tried a few options wrt to AutoLayout. One was using default cell and relying on it to sort its layout out another was to pin the default Description label to the edges on the ContentView the third was to add new UILabel as Subview and pin that to the ContentView. All with varying degrees of failureHollow
C
1

I had facing the same issue in my project. I had overcome that by the following way to set the height for the row.

 //calculate the height by this way
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return self.heightForBasicCell(at: indexPath)
    }


    func heightForBasicCell(at indexPath: IndexPath) -> CGFloat {
        var sizingCell: YourCell? = nil
        var onceToken: dispatch_once_t
        dispatch_once(onceToken, {() -> Void in
            sizingCell = tableView.dequeueReusableCell(withIdentifier: YourCell.cellIdentifier())!
        })
        self.configureBasicCell(sizingCell, at: indexPath)
        return self.calculateHeight(forConfiguredSizingCell: sizingCell)
    }

    func calculateHeight(forConfiguredSizingCell sizingCell: YourCell) -> CGFloat {
        sizingCell!.bounds = CGRect(x: 0.0, y: 0.0, width: CGRectGetWidth(tableView.frame), height: CGRectGetHeight(sizingCell!.bounds))
        sizingCell!.setNeedsLayout()
        sizingCell!.layoutIfNeeded()
        var size = sizingCell!.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
        return size.height + 1.0
        // Add 1.0f for the cell separator height
    }

    func configureBasicCell(_ cell: YourCell, at indexPath: IndexPath) {
//set your text here
    cell(“text”)
    }

Change code according to your need. I just converted objective C code to swift.

Castellanos answered 28/9, 2016 at 7:12 Comment(2)
I shouldn't need to calculate height "by hand". I don't do this anywhere else in our app.Hollow
Your are correct. you are not calculating height by hand. I guess you are using auto layouts, In cell based on text length set with label cell should increase their height right ?. For that you have to calculate by above way only. Give it a try once It will work.Castellanos

© 2022 - 2024 — McMap. All rights reserved.