如何在 UITableViewController 中设置静态单元格的自动高度?
Posted
技术标签:
【中文标题】如何在 UITableViewController 中设置静态单元格的自动高度?【英文标题】:How to set automatic height of static cell in UITableViewController? 【发布时间】:2015-06-04 18:32:13 【问题描述】:我正在使用 IB 和故事板,我定义了 UITableViewController
。我在那里定义了三个 static 单元格。前两个应该具有给定的高度,但最后一个应该自动填充剩余空间(锚定到视图底部)。我怎样才能做到这一点?我可以对单元格内部的控件使用自动布局,但单元格本身显示为灰色。
最好的解决方案是从 IB 执行此操作,但也欢迎程序化解决方案。
编辑:
这是它在我的故事板中的外观(颜色用于可视化单独的控件,每个控件都有所需的约束):
启动后: 请注意,文本视图在屏幕底部下方结束。
我忘了说我的目标是 ios 7.0+。
【问题讨论】:
【参考方案1】:您实际上可以将UITableViewAutomaticDimension
与静态单元格一起使用。按照惯例设计静态单元格,并通过添加手动将单元格设置为动态高度
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 240 // Something reasonable to help ios render your cells
现在覆盖 heightForRow
委托
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return UITableView.automaticDimension
我注意到使用此技术的唯一其他警告是您必须使用NSAutolayout
来创建对底部容器(UITableViewCell
的容器)的约束。因此,假设您在单元格的 contentView 中有一个容器,该容器将具有动态高度,要使其正确呈现,您需要创建一个底部空间约束。
如果您有一些具有固定高度的静态单元格,我建议通过在tableView:heightForRowAtIndexPath:indexPath
中打开行来返回该大小
【讨论】:
使用自动布局不是一个警告,它是一个功能! 非常适合我。我还实现了tableView.reloadData()
,以便在我更改此静态单元格中的内容时重新计算单元格高度。
@SwiftArchitect 非常正确,我想我的意思是“不要忘记”你的底部约束
设置rowHeight
和estimatedRowHeight
后,为什么还需要实现委托方法heightForRowAtIndexPath
?
@MrRogers 我猜是因为您可以为某些单元格设置自定义高度,并且默认实现会覆盖委托方法以使用这些高度【参考方案2】:
一定要覆盖 heightForRowAtIndexPath!否则,根据我的经验,它将无法正确显示
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
return UITableViewAutomaticDimension
【讨论】:
【参考方案3】:好的,试试这个
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
if indexPath.row == 0
return firstRowHeight
else if indexPath.row == 1
return secondRowHeight
else
return tableView.frame.size.height - firstRowHeight - secondRowHeight
唯一可能有问题的是这个方法要在视图设置tableView高度之前运行
【讨论】:
这是目前最好的选择。但是,我需要为第三行再减去 63 个像素,也许是为了导航栏? 所以63(好吧,实际上是64)是导航栏的高度+状态栏的高度。我有点奇怪tableView
height 确实包含它们……
通常你不应该减去导航。酒吧高度。使用视图调试查看实际的tableView高度是多少。【参考方案4】:
我在一篇博客文章中介绍了这一点,它使用静态表格视图并使用自动布局设置单元格高度。单元格都在界面生成器中定义。
您必须在代码中启用自动单元格高度,但这只是几行代码。
我展示了一切,包括 IB 和代码。
看看
http://www.oliverfoggin.com/using-a-static-uitableview-as-a-layout-device/
【讨论】:
这是我设置约束并返回UITableViewAutomaticDimension
的高度时的样子:link(请参阅更新的问题以供参考)。我也忘了提到我的目标是 iOS 7.0+。【参考方案5】:
如果整个 tableview 单元格高度是动态的,那么你可以试试这个
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 240
或者表格视图需要一些固定高度的单元格和一些动态高度的单元格,您可以查看答案 Dynamic & static tableview cell height
希望对你有帮助。
【讨论】:
在静态单元格中,这不起作用。但是tableView:heightForRowAtIndexPath:
的代理运行良好,因为UITableViewController
有自己的实现,关于如何获取单元格的高度。【参考方案6】:
不确定来自 IB 和使用自动布局
但是以编程方式使用,
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
使用此方法,您可以检查 indexpath.row。并使用它返回不同的高度。
【讨论】:
我当然知道那个方法,但问题是我应该为第三行返回什么......【参考方案7】:Ryan Romanchuk 的回答很棒。我有一个技巧可以帮助像我这样的初学者。
由于这是一个静态单元格案例,您可能倾向于对每个动态字段使用IBOutlet
。在tableView
加载循环之外的UILabel
中设置值将不会考虑新的高度。
要允许动态高度起作用,您可以在覆盖的cellForRowAtIndexPath
委托中分配值,以便自动布局可以获取新高度。如需更新字段,请致电tableView.reloadData()
。
【讨论】:
【参考方案8】:对于静态(非数据驱动)高度,您只需将单元格出列一次并存储高度:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
static NSNumber *height;
if (!height)
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"MyCustomCell"];
height = @(cell.bounds.size.height);
return [height floatValue];
【讨论】:
我不明白这对我有什么帮助……以上是关于如何在 UITableViewController 中设置静态单元格的自动高度?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 UITableViewController 之上添加 UIView [关闭]
如何将 UITableViewController 创建为可重用模块?
如何将 uitoolbar 添加到 uitableviewcontroller?
如何在当前 UITableViewController 上方添加一个 UIView
Swift:如何在 UITableViewController(包含 UICollectionView)中使用“didSelectItemAtIndexPath”?