UITableView dynamic cell heights only correct after some scrolling

后端 未结 24 1246
误落风尘
误落风尘 2020-11-29 16:41

I have a UITableView with a custom UITableViewCell defined in a storyboard using auto layout. The cell has several multiline UILabels.

相关标签:
24条回答
  • 2020-11-29 17:26

    None of the above solutions worked but the following combination of the suggestions did.

    Had to add the following in viewDidLoad().

    DispatchQueue.main.async {
    
            self.tableView.reloadData()
    
            self.tableView.setNeedsLayout()
            self.tableView.layoutIfNeeded()
    
            self.tableView.reloadData()
    
        }
    

    The above combination of reloadData, setNeedsLayout and layoutIfNeeded worked but not any other. Could be specific to the cells in the project though. And yes, had to invoke reloadData twice to make it work.

    Also set the following in viewDidLoad

    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = MyEstimatedHeight
    

    In tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)

    cell.setNeedsLayout()
    cell.layoutIfNeeded() 
    
    0 讨论(0)
  • 2020-11-29 17:27

    I don't know this is clearly documented or not, but adding [cell layoutIfNeeded] before returning cell solves your problem.

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        TableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"TestCell"];
        NSUInteger n1 = firstLabelWordCount[indexPath.row];
        NSUInteger n2 = secondLabelWordCount[indexPath.row];
        [cell setNumberOfWordsForFirstLabel:n1 secondLabel:n2];
    
        [cell layoutIfNeeded]; // <- added
    
        return cell;
    }
    
    0 讨论(0)
  • 2020-11-29 17:28

    Add a constraint for all content within a table view custom cell, then estimate table view row height and set row hight to automatic dimension with in a viewdid load :

        override func viewDidLoad() {
        super.viewDidLoad()
    
        tableView.estimatedRowHeight = 70
        tableView.rowHeight = UITableViewAutomaticDimension
    }
    

    To fix that initial loading issue apply layoutIfNeeded method with in a custom table view cell :

    class CustomTableViewCell: UITableViewCell {
    
    override func awakeFromNib() {
        super.awakeFromNib()
        self.layoutIfNeeded()
        // Initialization code
    }
    }
    
    0 讨论(0)
  • 2020-11-29 17:30

    I have tried most of the answers to this question and could not get any of them to work. The only functional solution I found was to add the following to my UITableViewController subclass:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        UIView.performWithoutAnimation {
            tableView.beginUpdates()
            tableView.endUpdates()
        }
    }
    

    The UIView.performWithoutAnimation call is required, otherwise you will see the normal table view animation as the view controller loads.

    0 讨论(0)
  • 2020-11-29 17:30

    Just make sure you're not setting the label text in 'willdisplaycell' delegate method of table view. Set the label text in 'cellForRowAtindexPath' delegate method for dynamic height calculation.

    You're Welcome :)

    0 讨论(0)
  • 2020-11-29 17:30

    In Swift 3. I had to call self.layoutIfNeeded() each time I update the text of the reusable cell.

    import UIKit
    import SnapKit
    
    class CommentTableViewCell: UITableViewCell {
    
        static let reuseIdentifier = "CommentTableViewCell"
    
        var comment: Comment! {
            didSet {
                textLbl.attributedText = comment.attributedTextToDisplay()
                self.layoutIfNeeded() //This is a fix to make propper automatic dimentions (height).
            }
        }
    
        internal var textLbl = UILabel()
    
        override func layoutSubviews() {
            super.layoutSubviews()
    
            if textLbl.superview == nil {
                textLbl.numberOfLines = 0
                textLbl.lineBreakMode = .byWordWrapping
                self.contentView.addSubview(textLbl)
                textLbl.snp.makeConstraints({ (make) in
                    make.left.equalTo(contentView.snp.left).inset(10)
                    make.right.equalTo(contentView.snp.right).inset(10)
                    make.top.equalTo(contentView.snp.top).inset(10)
                    make.bottom.equalTo(contentView.snp.bottom).inset(10)
                })
            }
        }
    }
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let comment = comments[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: CommentTableViewCell.reuseIdentifier, for: indexPath) as! CommentTableViewCell
            cell.selectionStyle = .none
            cell.comment = comment
            return cell
        }
    

    commentsTableView.rowHeight = UITableViewAutomaticDimension
        commentsTableView.estimatedRowHeight = 140
    
    0 讨论(0)
提交回复
热议问题