ios - 什么是 NSLayoutConstraint "UIView-Encapsulated-Layout-Height"以及我应该如何强制它干净地重新计算?

标签 ios uitableview cocoa-touch autolayout ios-autolayout

我有一个在 iOS 8 下运行的 UITableView,我在 Storyboard中使用来自约束的自动单元格高度。

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

我通过向 TextView 添加运行时约束并更改约束上的常量以响应用户事件来执行此操作:

-(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-Encapsulated-Layout-Height 是单元格首次呈现时的计算高度 - (我设置了我的 UITextView height >= 70.0) 然而,这个派生约束随后否决了更新的用户 cnstraint 似乎并不正确。

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

那么,什么是 NSLayoutConstraint UIView-Encapsulated-Layout-Height(我猜这是自动调整单元格大小的计算高度),我应该怎么做强制它干净地重新计算?

最佳答案

尝试将 _collapsedtextHeightConstraint 的优先级降低到 999。这样系统提供的 UIView-Encapsulated-Layout-Height 约束始终优先。

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

补充:虽然系统提供的约束是否正确可能值得商榷,但与框架抗争是没有意义的。简单地接受系统约束优先。如果您认为系统约束有误,请确保从委托(delegate)返回正确的 rowHeight。

关于ios - 什么是 NSLayoutConstraint "UIView-Encapsulated-Layout-Height"以及我应该如何强制它干净地重新计算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25059443/

相关文章:

ios - 委托(delegate)创建 ViewController 的新实例

ios - UIPageControl 项目符号改进了可访问性触摸语音

cocoa-touch - Cocoa Touch - 以编程方式添加 UIImageView?

objective-c - 带有用于 Objective-C 的 ClientLogin 接口(interface)的 Google App Engine

objective-c - 用户输入的字符串在应用首选项中保存为 URL

ios - 核心数据轻量级迁移后执行自定义代码

iOS 6 自定义分组 UITableViewCell 大小不正确

swift - UITableViewCell 子类 IBOutlets 返回 nil

swift - UIView drawRect 仅在 UITableViewCell 中调用一次,导致在重新使用单元格时产生陈旧数据

ios - AVAudioPlayer 音频中断和音量自行增加