简体   繁体   中英

Self-sizing UITableViewCell without Auto Layout

I'm trying to create a self-sizing UITableView but don't want to use Auto Layout to layout it's subviews.

Is there any way to do this? I'm setting

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 40

but adjusting self.frame.size.height in layoutSubviews doesn't help, the cell remains at 40 height, so I assume I need to return the real height in a different method. For UICollectionViewCells the method is

override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes

but I can't find the equivalent for UITableViewCell .

Thanks for any pointers.

You can't create a dynamic height tableViewCell without auto-layout , actually when you pass this UITableViewAutomaticDimension to a tableView's rowHeight it either

1- Return height specified in heightForCellAtRow if implemented

2- Return correct height from Xib or if you created constraints in code

3- If non-valid it will return 40 (default)

Implement self-sizing UITableViewCell without auto layout, you have to calculate the size yourself and return it inside sizeForRowAtIndexPath:

class Cell: UITableViewCell {
    ...
    func getCellHeight() -> CGFloat {
        // calculate height yourself
    }
    ...
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    guard let cell = tableView.cellForRow(at: indexPath) as? Cell else { return defaultHeight }
    return cell.getCellHeight
}

Or you can override sizeToFit() , sizeThatFits(size: CGSize) to calculate your expected height and call these method when you need.

It's actually doable and it's a very good approach to do so without auto layout (if you want smooth scrolling on your TableView ).

You can achieve this by using sizeThatFits(_ size: CGRect) method to calculate the size of your cell by considering all the views/paddings inside your cell. Then you will have to let the TableView know about that by using autoDimension rowHight as you also did yourself, but also in func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat method:

UITableView setup:

tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = UITableView.automaticDimension

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableView.automaticDimension
}

Keep in mind, if you have labels with dynamic texts in your cell, you need to set the texts inside the sizeThatFits(_ size: CGRect) method and calculate the label height from there.

UITableViewCell:

    let cellLabel = UILabel()
    var labelText: String?
    private let padding: CGFloat = 8

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        guard let text = self.labelText else { return .zero } // You might not need this

        let superHeight = super.sizeThatFits(size).height
        let verticalPadding = padding * 2

        descriptionLabel.text = text
        descriptionLabel.font = UIFont.rpx.regular14

        let labelHeight = labelHeight.text?.boundingRect(
            with: CGSize(width: size.width, height: size.height),
            options: .usesLineFragmentOrigin,
            context: nil
        ).size.height ?? size.height

        return CGSize(width: size.width, height: superHeight + labelHeight + verticalPadding)
    }
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
let maxLabelWidth:CGFloat = tableView.frame.width
let title = UILabel()
label.numberOfLines = 0
let titleFont = [NSFontAttributeName: UIFont(name: "OpenSans", size: 10.0)! ]
let titleStr = "test Str" // update with your title string from Array
label.attributedText = NSMutableAttributedString(string: titleStr , attributes: titleFont)
let updatedSize:CGSize = title.sizeThatFits(CGSizeMake(maxLabelWidth, CGFloat.max))
let updatedHeight = updatedSize.height
return updatedHeight
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM