NSLayoutConstraint「UIView-Encapsulated-Layout-Height」とは何ですか? また、これを強制的にきれいに再計算するにはどうすればいいですか? 質問する

NSLayoutConstraint「UIView-Encapsulated-Layout-Height」とは何ですか? また、これを強制的にきれいに再計算するにはどうすればいいですか? 質問する

私はUITableViewiOS 8 で実行しており、ストーリーボードの制約から自動セルの高さを使用しています。

セルの 1 つに 1 つのテキストが含まれており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 は私が計算した高さで、その他の制約はUITextViewXcode/IB から得たものです。

UIView-Encapsulated-Layout-Height最後の 1 つは、セルが最初にレンダリングされるときに計算された高さであると思われます(UITextView高さを >= 70.0 に設定しました)。ただし、この派生制約によって更新されたユーザー制約が上書きされるのは正しくないようです。

さらに悪いことに、レイアウト コードは高さの制約を破ろうとしているように見えますが、実際には破っていません。セルの高さが再計算され、すべてが希望どおりに描画されます。

それで、それは何ですかNSLayoutConstraint UIView-Encapsulated-Layout-Height(自動セル サイズ設定用に計算された高さだと思います)、そしてそれを強制的にきれいに再計算するにはどうすればよいでしょうか?

ベストアンサー1

優先度を_collapsedtextHeightConstraint999 に下げてみてください。こうすることで、システムが提供するUIView-Encapsulated-Layout-Height制約が常に優先されます。

これは、 で返される内容に基づきます-tableView:heightForRowAtIndexPath:。正しい値を返すようにしてください。また、独自の制約と生成された制約は同じである必要があります。独自の制約の優先度を低くする必要があるのは、折りたたみ/展開アニメーションの実行中に競合を防ぐためだけです。

追加: システムが提供する制約が正しいかどうかは議論の余地があるかもしれませんが、フレームワークと争っても意味がありません。システム制約が優先されることを単純に受け入れてください。システム制約が間違っていると思われる場合は、デリゲートから正しい rowHeight を返すようにしてください。

おすすめ記事