我在最新调查结果后完全修改了这个问题。
我的目标是实现以下效果:
请注意,我知道,这可以通过插入/删除所选单元格I already have a successful implementation using that method下方的单元格来实现。
这一次,我想尝试使用自动布局约束来实现这一目标。
我有sample project available for anyone to check,还有opened an issue。总而言之,这是我迄今为止所尝试的内容:
我有以下观点作为演员:
我已按照以下方式在我的单元格中设置了自动布局约束(请注意,这是严格的伪语言):
我有一个自定义UITableViewCell
子类,有多个出口,但最重要的是前面提到的高度约束的出口:这里的想法是默认将其constant
设置为0,但是当选择单元格时,将其设置为44,使其变为可见:
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
detailViewHeightConstraint.constant = selected ? detailViewDefaultHeight : 0
UIView.animateWithDuration(0.3) {
self.layoutIfNeeded()
}
}
我有以下结果:
所以效果是有效的,但不是我最初的想象。我不希望推出主视图,而是在显示详细视图时希望单元格的高度增长,而当隐藏它时,缩小 。
我在运行时检查了我的布局层次结构:
我需要的是以下内容:表格视图单元格内容视图的高度应该等于
我如何设置约束来实现这一目标?
答案 0 :(得分:13)
经过大量研究,我认为我已经在this great article.
的帮助下找到了解决方案以下是调整单元格大小所需的步骤:
在Main和Detail Views中,我最初将标签设置为水平和垂直居中。这对于自我调整细胞来说还不够。我需要的第一件事是使用垂直间距约束而不是简单对齐来设置我的布局:
此外,您应将主容器的垂直抗压力设置为1000。
细节视图有点棘手:除了创建适当的垂直约束外,您还必须使用它们的优先级来达到预期的效果:
主要想法如下:
我必须修改我的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
}
结果如下:
单元格现在可以正确调整大小。你可能会注意到动画仍然有点奇怪,但修复它不属于这个问题的范围。
结论:这比应该的更难。我真的希望将来看到一些改进。
答案 1 :(得分:-1)
这是obj-c,但我确定你会处理这个问题:
添加viewDidLoad:
self.tableView.estimatedRowHeight = self.tableView.rowHeight;
self.tableView.rowHeight = UITableViewAutomaticDimension;
这将为tableView启用自定义单元格,并且应该可以在iOS8 +上运行