Ios 使用自动布局约束动态调整表视图单元格的大小 更新
根据我的最新发现,我已经完全修改了这个问题 目标 我的目标是实现以下效果:Ios 使用自动布局约束动态调整表视图单元格的大小 更新,ios,uitableview,autolayout,ios-autolayout,Ios,Uitableview,Autolayout,Ios Autolayout,根据我的最新发现,我已经完全修改了这个问题 目标 我的目标是实现以下效果: 有一个简单的表视图 用户选择一行 选定的行将展开,显示原始行下方的另一个标签 请注意,我知道,这可以通过插入/删除选定单元格下方的单元格来实现 这一次,我想尝试使用自动布局约束来实现这一点 现状 我有一个朋友,还有。总而言之,以下是我迄今为止所做的尝试: 作为演员,我有以下观点: 单元格的内容视图 包含主标签(“主视图”)的俯视图 主视图下方的底部视图,包含最初隐藏的标签(“详细视图”) 我已通过以下方式在单元格中设
- 单元格的内容视图
- 包含主标签(“主视图”)的俯视图
- 主视图下方的底部视图,包含最初隐藏的标签(“详细视图”)
- mainView.top=contentView.top
- mainView.leading=contentView.leading
- mainView.training=contentView.training
- mainView.bottom=detailView.top
- detailView.leading=contentView.leading
- detailView.training=contentView.training
- detailView.bottom=contentView.bottom
- detailView.height=0
UITableViewCell
子类,具有多个出口,但这里最重要的是前面提到的高度约束的出口:这里的想法是默认将其常量设置为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()
}
}
我有以下结果:
所以效果是有效的,但不是我最初想象的那样。我不希望将主视图向上推,而是希望在显示细节视图时单元格的高度增大,而在隐藏视图时缩小
我在运行时检查了布局层次结构:
- 初始状态正常。内容视图的高度等于我的主视图的高度(在本例中为125点)
- 选择单元后,局部视图的高度约束将增加到44个点,两个视图将正确垂直堆叠。但不是单元的内容视图扩展,而是主视图缩小
问题:
我需要的是:表格视图单元格的内容视图的高度应该等于
- 当局部视图的高度约束为0时,主视图的高度(当前有效)
- 正确设置局部视图的高度约束时,主视图高度+局部视图高度(这不起作用)
我必须如何设置我的约束才能实现这一点?这是在obj-c中,但我相信您会处理这一点:
添加您的viewDidLoad:
self.tableView.estimatedRowHeight=self.tableView.rowHeight;
self.tableView.rowHeight=UITableViewAutomaticDimension代码>
这将为您的tableView启用自调整单元格大小,并且应该可以在iOS8+上工作。经过大量的研究,我想我已经在
以下是调整单元格大小所需的步骤:
在主视图和详图视图中,我最初将标签设置为水平和垂直居中。这对于自动调整单元格大小是不够的。我需要做的第一件事是使用垂直间距约束而不是简单对齐来设置布局:
此外,应将主容器的垂直压缩阻力设置为1000
细节视图有点棘手:除了创建适当的垂直约束外,还必须处理它们的优先级以达到所需的效果:
- 细节容器的高度被限制为44个点,但为了使其可选,将其优先级设置为999(根据文档,任何低于“必需”的都将被视为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(\uquo:didselectrowatinexpath:)
:
请注意,我引入了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 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
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.contentInset.top = statusbarHeight
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 125
}