经过大量研究后,我想我已经在以下帮助下找到了解决方案这篇很棒的文章。 http://pivotallabs.com/expandable-uitableviewcells/
以下是调整单元格大小所需的步骤:
在主视图和详细视图中,我最初将标签设置为水平和垂直居中。这对于自调整大小的单元来说是不够的。我需要的第一件事是使用垂直间距约束而不是简单的对齐来设置布局:
此外,您应该将主容器的垂直压缩阻力设置为 1000。
细节视图有点棘手:除了创建适当的垂直约束之外,您还必须调整它们的优先级以达到所需的效果:
- 详细信息容器的高度被限制为 44 点,但为了使其可选,请将其优先级设置为 999(根据文档,任何低于“必需”的值都将被视为如此)。
- 在详细信息容器中,设置垂直间距约束,并为其指定优先级 998。
主要思想如下:
- 默认情况下,单元格是折叠的。为此,我们必须以编程方式将详细信息容器的高度约束常量设置为 0。由于其优先级高于单元格内容视图内的垂直约束,因此后者将被忽略,因此详细信息容器将被隐藏。
- 当我们选择单元格时,我们希望它展开。这意味着,垂直约束必须进行控制:我们将优先级详细信息容器的高度约束设置为较低的值(我使用的是 250),因此它将被忽略,以支持内容视图中的约束。
我必须修改我的UITableViewCell
支持这些操作的子类:
// `showDetails` is exposed to control, whether the cell should be expanded
var showsDetails = false {
didSet {
detailViewHeightConstraint.priority = showsDetails ? lowLayoutPriority : highLayoutPriority
}
}
override func awakeFromNib() {
super.awakeFromNib()
detailViewHeightConstraint.constant = 0
}
要触发该行为,我们必须覆盖tableView(_:didSelectRowAtIndexPath:)
:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: false)
switch expandedIndexPath {
case .Some(_) where expandedIndexPath == indexPath:
expandedIndexPath = nil
case .Some(let expandedIndex) where expandedIndex != indexPath:
expandedIndexPath = nil
self.tableView(tableView, didSelectRowAtIndexPath: indexPath)
default:
expandedIndexPath = indexPath
}
}
请注意我已经介绍了expandedIndexPath
跟踪我们当前扩展的索引:
var expandedIndexPath: NSIndexPath? {
didSet {
switch expandedIndexPath {
case .Some(let index):
tableView.reloadRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Automatic)
case .None:
tableView.reloadRowsAtIndexPaths([oldValue!], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
}
设置该属性将导致表视图重新加载适当的索引,这为我们提供了一个绝佳的机会来告诉单元格是否应该扩展:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! ExpandableTableViewCell
cell.mainTitle = viewModel.mainTitleForRow(indexPath.row)
cell.detailTitle = viewModel.detailTitleForRow(indexPath.row)
switch expandedIndexPath {
case .Some(let expandedIndexPath) where expandedIndexPath == indexPath:
cell.showsDetails = true
default:
cell.showsDetails = false
}
return cell
}
最后一步是启用自调整大小viewDidLoad()
:
override func viewDidLoad() {
super.viewDidLoad()
tableView.contentInset.top = statusbarHeight
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 125
}
结果如下:
细胞现在可以正确调整自身大小。您可能会注意到动画仍然有点奇怪,但是解决这个问题不属于这个问题的范围。
结论:这比应有的要困难得多。 ????我真的希望未来能看到一些改进。