iOS使用AutoLayout单击时展开UITableViewCell

Mic*_*ala 5 uitableview ios autolayout

我正在开发简单的应用程序,现在我专注于在用户点击该单元格后扩展UITableViewCell.它是iOS 8应用程序所以我设置:

self.tableVIew.rowHeight = UITableViewAutomaticDimension
self.tableVIew.estimatedRowHeight = 50
Run Code Online (Sandbox Code Playgroud)

单元格约束如下所示:

在此输入图像描述

如果用户点击单元格,则调用此函数:

func extend() {
        self.contentView.removeConstraint(self.bottomConstraint)

        let additionalView = UIView()
        additionalView.setTranslatesAutoresizingMaskIntoConstraints(false)
        additionalView.backgroundColor = UIColor.orangeColor()
        self.contentView.addSubview(additionalView)
        self.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[additionalView(50)]-5-|", options: nil, metrics: nil, views: ["additionalView" : additionalView]))
        self.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-5-[additionalView(100)]-5@999-|", options: nil, metrics: nil, views: ["additionalView" : additionalView]))
    }
Run Code Online (Sandbox Code Playgroud)

self.bottomConstraint是绿色圆圈底部和单元格contentView底部之间的costraint.

问题是:为什么只有在约束中设置了优先级时此解决方案才有效:

V:|-5-[additionalView(100)]-5@999-|
Run Code Online (Sandbox Code Playgroud)

没有明确的优先级我得到错误:

(
    "<NSLayoutConstraint:0x7a63f7a0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7a737840(60)]>",
    "<NSLayoutConstraint:0x7a644f40 V:|-(5)-[UIView:0x7a63f2a0]   (Names: '|':UITableViewCellContentView:0x7a737840 )>",
    "<NSLayoutConstraint:0x7a644fb0 V:[UIView:0x7a63f2a0(100)]>",
    "<NSLayoutConstraint:0x7a644f70 V:[UIView:0x7a63f2a0]-(5)-|   (Names: '|':UITableViewCellContentView:0x7a737840 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7a644f70 V:[UIView:0x7a63f2a0]-(5)-|   (Names: '|':UITableViewCellContentView:0x7a737840 )>
Run Code Online (Sandbox Code Playgroud)

Mik*_*and 0

'UIView-Encapsulated-Layout-Height'是表视图系统计算出行高后创建的行高约束。简单地更改内部约束不足以强制重新计算。

这并不是什么新的意外行为;而是一种新的行为。虽然有时可以通过让单元格悬挂在表视图提供的高度之外来实现效果,但表视图数据源委托旨在提供“官方”行高。

Apple 的示例项目“表视图动画和手势”就是说明性的。它尚未针对 iOS 8 的自动调整单元格大小进行更新,但无论如何都值得一看。在APLTableViewController.m中,tableViewController 是单元格俯仰手势的委托,因为它需要调整高度。它的handlePinch:调用updateForPinchScale: atIndexPath:可以按照您想要的方式进行扩展。

表视图控制器不会尝试直接更改行高。首先,它设置自己的自定义数据源对象(称为sectionInfo)以提供行高的更新值[sectionInfo replaceObjectInRowHeightsAtIndex:indexPath.row withObject:@(newHeight)]; 。然后表视图控制器执行以下操作:

BOOL animationsEnabled = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
[self.tableView beginUpdates];
[self.tableView endUpdates];
[UIView setAnimationsEnabled:animationsEnabled]; 
Run Code Online (Sandbox Code Playgroud)

关闭所有 UIView 动画是因为这是一个紧要关头,所以它应该立即改变而不会出现抖动。由于您只想进行一次性更改,因此您应该尝试不同的动画设置以获得您想要的效果。

它们的关键是一对beginUpdates/endUpdates调用,这显然会触发系统重新计算行高。对于新的 iOS 自动调整单元格大小,只需更改约束并调用这些方法可能就足够了;你也可以尝试夹心reloadRowsAtIndexPaths:withRowAnimation:UITableViewRowAnimationNone