web-dev-qa-db-ja.com

プログラムで自動レイアウト制約を変更した後、ビューが更新されない

事前に、私は実際に私が望んでいた目に見える効果を得たが、満足のいく方法ではなかったことを言わなければなりません。

UITableViewを保持するViewControllerを取得しました。 tableViewの高さは、0(表示されない)から、保持する行数まで変化します。高さは、現在の行数に行の高さを掛けることにより、ViewControllerのviewDidLoad()で計算されます。

私が最初に試したのは、ストーリーボードで設定された高さ制約に接続された_@IBOutlet weak var tableHeightConstraint: NSLayoutConstraint!_を作成することでした。ランダムな初期の高さだけがありますが、ViewControllerのviewDidLoad()内で正しい値に更新され、必要に応じてビューを更新するメソッドが続きます。

_tableHeightConstraint = NSLayoutConstraint(item: tableView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0, constant: calculatedTableViewHeight)

// At this point I've tried a variety of methods like the following two but actually none has worked for me
view.layoutIfNeeded()

// or
view.updateConstraints()

// or
view.layoutSubviews()
_

...そして、tableViewの同じメソッドでさえ、念のために、これらすべてをviewDidLayoutSubviews()に入れています。

したがって、次に試したのは、上記と同じ制約を作成することでしたが、更新する代わりにビューに追加しました:view.addConstraint(tableHeightConstraint)。これは実際には望ましい視覚効果をもたらしましたが、ログではこれら2つの高さの制約の競合が発生し、最初の制約が壊れました。私の目標は、正確でクリーンなコードを取得することであるため、私はこれまでも努力を続けてきました。したがって、今回は、調整済みの制約を再度追加する前に、最初に制約をビューから削除しました。視覚的にも、すべてが完璧でしたが、相反する制約を取り除くことはできませんでした。

したがって、私の実際の質問は(これまで間違っていたことに加えて)、既存の制約を更新してから、ビューとそのサブビューの適切な更新/再レイアウトを任意の時点で更新する方法です。ビューまたはユーザーが対話するときにいくつかの制約を変更するかどうか。助けてくれてありがとう!

17
Alexei S.

現在、現在の制約を更新するのではなく、新しい制約を割り当てています。新しい制約もビュー階層に追加されていません。

IBOutletを使用してIBで設定した制約を参照するアプローチは優れたアプローチですが、その変数に新しい制約を割り当てる代わりに、制約の定数を変更するだけです。

_tableHeightConstraint.constant = calculatedTableHeight_。

ここでlayoutIfNeeded()を呼び出す必要はありません。定数を変更すると、制約はレイアウトパスの呼び出しを自動的に処理するからです。 updateConstraints()layoutSubviews()は間違いなくあなたが望むものではありません。

30
cmyr