【问题标题】:UITableViewAutomaticDimension not working until scrollUITableViewAutomaticDimension 在滚动之前不起作用
【发布时间】:2015-03-06 17:21:44
【问题描述】:

第一次加载表格视图时,所有可见单元格都是估计的行高。当我向下滚动时,单元格会自动调整大小,当我向上滚动时,最初估计的单元格会自动调整大小。

一旦单元格被自动调整大小,它们似乎永远不会回到估计的RowHeight。

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 开始,这不再是问题

【问题讨论】:

  • 还要注意,我的 AutoLayout 约束设置正确(三重检查)
  • 我遇到了类似的问题。我可以通过设置控制 tableCell 高度的约束来解决它而无需重新加载表格部分 - 在我的情况下,将内容视图 bottomMarginTop 固定到 textView 底部的约束优先级为 1000。即使这会导致不可满足的约束错误,最终结果是表格视图单元格正确显示。
  • 这在 Xcode 9.2 中仍然是一个问题

标签: ios uitableview swift uikit


【解决方案1】:

在您的表格加载后调用“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)

【讨论】:

  • 这是一个解决方案,但不是必须的。
  • 这是错误答案,您应该在约束或代码中发现错误
  • 可悲的是,即使我现在至少重建了 5 次自己的约束,我开始认为这是 Apple 实现 UITableViewAutomaticDimension 中的一个错误。它似乎会自动添加高度约束,使单元格扩大或缩小,并且在重用单元格时它会起作用......
  • 添加了 Swift 3 版本。谢谢@blankarsch
  • 注意:您必须在调用 reloadData 之前重新加载这些部分
【解决方案2】:

我遇到了同样的问题,发现 accessory cell.accessoryType 在不是 None 时会自动调整大小,所以目前它似乎是 Xcode 中的一个错误。

但正如@Blankarsch 提到的,如果您需要配件,致电reloadSections(..) 有助于解决此问题。

【讨论】:

  • 将其设置为 none 可以解决此问题。希望这个问题在今天之后消失。
  • 将附件类型更改为无对我来说对这个问题没有影响(Xcode 9.2)
【解决方案3】:

我认为here 的答案副作用较少。具体在tableView:cellForRowAtIndexPath:中添加cell.layoutIfNeeded()

我也在做@nosov 建议的好的做法,但还没有测试它们是否需要同时完成。

【讨论】:

  • 当我的 UILabel 的内容仅比可用空间宽几个像素时,这解决了我的问题(如果我将单元格滚动出视图并返回,它有时会正确调整大小)。
【解决方案4】:

只需像这样覆盖估计的HeightForRowAtIndexPath

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

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

【讨论】:

  • 在文档和涵盖此内容的 WWDC 会议中出于性能原因,建议不要这样做。
  • @jjatie 哪个会话?
  • @Jaybo 我可能应该记下。我很确定它在 2015 年的 Auto Layout 之谜中。
【解决方案5】:

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

【讨论】:

  • 尝试删除viewDidLoad方法中的self.tableView.estimatedRowHeight = 80.0这一行。有用吗?
  • 确实如此!我已经使用了 1 到 120 之间的估计值,但没有成功。我担心在单元格大小变化更大的较大数据集中,如果没有将estimatedRowHeight 属性设置为合理的值,滚动性能会受到损害。
【解决方案6】:

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

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

【讨论】:

  • 很好的答案,但我的特定问题在 Xcode 7 beta 6 中已修复
【解决方案7】:
func tableView(_ tableView: UITableView, 
  cellForRowAt indexPath: IndexPath) -> UITableViewCell


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

在函数中将单元格设置为首选内容,以便 UITableViewAutomaticDimension 正常工作。

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

【讨论】:

  • 虽然可能是这样,但当时并没有解决问题。 SDK 中有一个错误,现在似乎已解决;我的错误报告已作为副本关闭。
【解决方案8】:

确保在tableView:cellForRowAt: 中初始化您的单元格。当我在tableView:willDisplay:forRowAt: 中设置单元格内容时,即使使用 Xcode 8,我也遇到了这个问题

【讨论】:

    【解决方案9】:

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

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

    【讨论】:

      【解决方案10】:

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

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

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

      【讨论】:

        【解决方案11】:

        Xcode 9.3,斯威夫特 4.1 添加

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

        除了

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

        为我工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-04-19
          • 1970-01-01
          • 1970-01-01
          • 2016-04-07
          • 1970-01-01
          • 2015-07-29
          • 2011-06-25
          相关资源
          最近更新 更多