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
}
对我有用。
首次加载 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:
对我来说,只有在使用 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
}
对我有用。