UITableViewAutomaticDimension 在滚动之前不工作

UITableViewAutomaticDimension not working until scroll

首次加载 Table 视图时,所有可见单元格都是 estimatedRowHeight。当我向下滚动时,单元格会自动调整大小,当我向上滚动时,最初 estimatedRowHeight 的单元格会自动调整大小。

自动调整单元格大小后,它们似乎永远不会恢复为估计的行高度。

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
    self.tableView.estimatedRowHeight = 80.0
    self.tableView.rowHeight = UITableViewAutomaticDimension

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem()
}

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cellIdentifier = "Cell"
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as CustomTableViewCell

    // Configure the cell...
    let restaurant = restaurants[indexPath.row]
    cell.namelabel.text = restaurant.name
    cell.locationlabel.text = restaurant.location
    cell.typelabel.text = restaurant.type
    cell.thumbnailImageView.image = UIImage(named: restaurant.image)
    cell.thumbnailImageView.layer.cornerRadius = cell.thumbnailImageView.frame.size.width / 2
    cell.thumbnailImageView.clipsToBounds = true
    cell.accessoryType = restaurant.isVisited ? .Checkmark : .None

    return cell
}

关于如何让单元格最初自动调整大小的想法?

更新: 从 Xcode 7 beta 6 开始,这不再是问题

只需在 Table 加载后调用 "reloadSections":

self.tableView.reloadSections(NSIndexSet(indexesInRange: NSMakeRange(0, self.tableView.numberOfSections())), withRowAnimation: .None)

或在Swift 3:

let range = Range(uncheckedBounds: (lower: 0, upper: self.tableView.numberOfSections))
self.tableView.reloadSections(IndexSet(integersIn: range), with: .none)

只需确保您的标签没有在 Interface Builder 中设置明确的内容大小。它们必须像下面的屏幕截图一样是自动的,这样自动行高才能正常工作,而无需预先重新加载任何部分。

像这样覆盖 estimatedHeightForRowAtIndexPath

(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewAutomaticDimension;
}

并在 CustomTableViewCell 视图中检查您的自动布局约束。

我 运行 遇到了同样的问题,发现 accessory cell.accessoryType 在没有 None 时会干扰自动调整大小,所以目前看来 Xcode 中有一个错误。

但是正如@Blankarsch 提到的,如果您需要配件,调用 reloadSections(..) 有助于解决这个问题。

我认为 here 的答案副作用较小。具体在 tableView:cellForRowAtIndexPath:

中添加 cell.layoutIfNeeded()

我也在按照@nosov 的建议进行操作,这是一种很好的做法,但尚未测试它们是否需要同时进行。

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


- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath;

在函数中设置具有首选内容的单元格,以便 UITableViewAutomaticDimension 完美工作。

问题是因为单元格内容是在其他一些委托函数中加载的,所以你可以看到单元格自动调整到需要的大小。

如果您根据单元格本身(而不是单元格内容视图)设置约束,table 将无法获得正确的大小。因此,要解决此问题,您的约束必须设置为内容视图。

但是,当您的单元支持两种配置 with/without 附件视图时,这就是问题。在这种情况下,内容视图会根据附件视图调整大小,结果可能不是用户所期望的。因此,在这种情况下,一个解决方案是设置 2 个约束,一个用于单元格,第二个 具有较低优先级 的单元格内容视图。

确保在 tableView:cellForRowAt: 中初始化您的单元格。当我在 tableView:willDisplay:forRowAt:

中设置单元格内容时,即使 Xcode 8 我已经 运行 解决了这个问题

对我来说,只有在使用 willDisplay 单元格设置标签文本时才会遇到这个问题

如果我在 cellForRowAt 索引路径中设置我的标签文本,一切都很好

对我来说,解决这个问题的是@[David Hernandez] 答案的组合。

删除了上面的选择,在 Cell 的 layoutSubviews 中,我将 preferredMaxLayoutWidth 设置为这样(将 30 更改为您想要的左右间距)

-(void) layoutSubviews {
    [super layoutSubviews];
    self.textDescriptionLabel.preferredMaxLayoutWidth = self.frame.size.width - 30;
}

Xcode9.3,Swift4.1 添加

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

除了

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

对我有用。