当前位置: 首页 > 知识库问答 >
问题:

NSLayoutConstraint“UIView封装布局高度”是什么?我应该如何强制它干净地重新计算?

闻人嘉悦
2023-03-14

我有一个运行在iOS8下的UITableView,我在故事板中使用来自约束的自动单元格高度。

我的一个单元格包含一个UITextView,我需要它根据用户输入收缩和展开-点击可收缩/展开文本。

我通过向文本视图添加运行时约束并根据用户事件更改约束上的常量来实现这一点:

-(void)collapse:(BOOL)collapse; {

    _collapsed = collapse;

    if(collapse)
        [_collapsedtextHeightConstraint setConstant: kCollapsedHeight]; // 70.0
    else
        [_collapsedtextHeightConstraint setConstant: [self idealCellHeightToShowFullText]];

    [self setNeedsUpdateConstraints];

}

执行此操作时,我将其包装在tableView更新中,并调用[tableView setNeedsUpdateConstraints]

[tableView beginUpdates];

[_briefCell collapse:!_showFullBriefText];

[tableView setNeedsUpdateConstraints];
// I have also tried 
// [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
// with exactly the same results.

[tableView endUpdates];

当我执行此操作时,我的单元格确实会展开(并在进行此操作时设置动画),但我会收到一条约束警告:

2014-07-31 13:29:51.792 OneFlatEarth[5505:730175] Unable to simultaneously satisfy constraints.

Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 

(

    "<NSLayoutConstraint:0x7f94dced2b60 V:[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...'(388)]>",

    "<NSLayoutConstraint:0x7f94dced2260 V:[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...']-(15)-|   (Names: '|':UITableViewCellContentView:0x7f94de5773a0 )>",

    "<NSLayoutConstraint:0x7f94dced2350 V:|-(6)-[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...']   (Names: '|':UITableViewCellContentView:0x7f94de5773a0 )>",

    "<NSLayoutConstraint:0x7f94dced6480 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7f94de5773a0(91)]>"
 )

Will attempt to recover by breaking constraint 

<NSLayoutConstraint:0x7f94dced2b60 V:[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...'(388)]>

388是我计算的高度,UITextView上的其他约束是我从Xcode/IB得到的。

最后一个问题困扰着我-我猜UIView封装布局高度是第一次渲染单元格时计算的高度-(我将我的UITextView高度设置为

更糟糕的是,尽管布局代码说它试图打破我的高度限制,但它没有——它继续重新计算单元格高度,一切都按照我的意愿绘制。

那么,什么是NSLayoutConstraintui查看封装布局高度(我猜它是自动调整单元格大小的计算高度)以及我应该如何强制它干净地重新计算?


共有3个答案

钱弘壮
2023-03-14

99.9%的情况下,当使用自定义单元格或标头时,当表第一次加载时,所有UITableViews的冲突都会发生。一旦加载,您通常不会再看到冲突。

发生这种情况是因为大多数开发人员通常使用某种固定高度或锚约束来布局单元格/标头中的元素。发生冲突是因为当UITableView第一次加载/布局时,它将其单元格的高度设置为0。这显然与你自身的约束相冲突。要解决这个问题,只需将任何固定的高度约束设置为较低的优先级(. defaultHigh)。仔细阅读控制台消息,看看布局系统决定打破哪个约束。通常这是一个需要改变其优先级的。您可以这样更改优先级:

let companyNameTopConstraint = companyNameLabel.topAnchor.constraint(equalTo: companyImageView.bottomAnchor, constant: 15)
    companyNameTopConstraint.priority = .defaultHigh

NSLayoutConstraint.activate([
            companyNameTopConstraint,
           the rest of your constraints here
            ])
阎德义
2023-03-14

我有一个类似的场景:一个只有一行单元格的表视图,其中有几行UILabel对象。我正在使用iOS 8和自动布局。

当我旋转时,我得到了错误的系统计算的行高度(43.5远小于实际高度)。它看起来像:

"<NSLayoutConstraint:0x7bc2b2c0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7bc37f30(43.5)]>"

这不仅仅是一个警告。我的表格视图单元的布局很糟糕——所有文本都重叠在一个文本行上。

下面这行神奇地“修复”了我的问题,这让我感到惊讶(autolayout没有任何抱怨,我在屏幕上得到了我期望的结果):

myTableView.estimatedRowHeight = 2.0; // any number but 2.0 is the smallest one that works

有或没有这一行:

myTableView.rowHeight = UITableViewAutomaticDimension; // by itself this line only doesn't help fix my specific problem
艾阳羽
2023-03-14

尝试将\u collapsedtextHeightConstraint的优先级降低到999。这样,系统提供的ui视图封装布局高度约束始终优先。

它基于您在-tableView:heightforrowatinexpath:中返回的内容。确保返回正确的值和您自己的约束,并且生成的约束应该相同。您自己的约束的较低优先级仅在折叠/展开动画运行时临时需要,以防止冲突。

另外:虽然系统提供的约束是否正确可能有争议,但与框架抗争没有任何意义。只需接受系统约束优先。如果认为系统约束错误,请确保从代理返回正确的行高。

 类似资料:
  • 问题内容: 我已经使用以下命令从Docker文件构建了一个Docker映像。 当我尝试使用同一命令重建它时,它正在使用构建缓存,例如: 缓存显示已安装Aerospike。但是,我在从该图像生成的容器中找不到它,因此我想在不使用缓存的情况下重建该图像。如何强制Docker在没有缓存的情况下重建干净的映像? 问题答案: 有一个选项: 在较旧的Docker版本中,您需要通过,但情况不再如此。

  • 执行appendChild或removeChild时,会重新计算布局吗?什么时候重新计算布局? 猜测: 在事件循环中,有一阶段是留给渲染的,是否是在这时重新计算布局?appandChild或removeChild只是改变了dom。 在渲染阶段根据改变的这个dom来重新计算布局。 如果我添加了一个元素紧接着又删除了,渲染阶段是根本不知道的。即使这个元素上有动画也是不会出现的。 可以试一下这个例子co

  • 我使用的是ZF2 skeleton应用程序,它有一个.gitignore,可以防止外部库提交到git。在调试过程中,我喜欢在库的源代码中到处更改内容,以了解如何工作。如果这些是版本控制的,将很容易将它们恢复到原始状态。 如何强制Composer重新安装特定的框架,以便再次获得新的未修改副本? PS:请不要建议删除.gitignore文件,因为它存在是有原因的;它阻止我的第三方库进入我的应用程序存储

  • 问题内容: 我正在使用Max OS X Mountain Lion,java -version返回“ 1.6.0_37”。但是我无法使用导入的com.apple.eawt。*类编译项目。 我必须安装什么才能在系统上安装Apple Java Extensions? 任何帮助,将不胜感激! 更新 : 我从编译器收到以下错误: 更新2 : XCode版本4.5.2已安装 更新3 : 我的问题的原因是在类

  • 问题内容: 我已经阅读了一些文章,但没有得到实际的信息。有人可以向我解释。 仅与IE6相关吗? 这是什么? 是IE唯一的TAG吗? 编辑: 我发现此信息对我很有帮助 由于Internet Explorer很老(因为它是最早可用的浏览器之一),所以它没有像现在的浏览器那样重新启动。因此,随着时间的流逝,Microsoft开始改编新引擎以使用CSS。看起来不错……但是,CSS改变了Internet E

  • 我有以下课程: 这只是其中一个例子,我有一些类似的其他类,我将它们作为依赖注入到其他类中。但是它使我的SchemaFetcher类像一个单例,我不断地向它的每一个方法传递模式定义。这似乎是非常程序化的,我想实际上使模式定义成为数据库模式获取类的实例变量,但在这种情况下,我将无法将模式获取对象注入到我的验证器类中,相反,我应该这样做 但这使我与fetcher紧密耦合,这就是为什么我想首先使用依赖注入