70

すべてのボタンにパディングを追加したいので、UIButton をサブクラス化し、setFrame メソッドを使用して固定パディングを追加したいと考えました。setFrame を除いて、すべてが機能していました。調べてみたところ、そのビューで「AutoLayout を使用する」のチェックを外すと、setFrame を使用できることがわかりました。これを回避する方法はありますか?iphone 5 以前のデバイスの両方でアプリの見栄えを良くするのに役立つので、私は本当に autolayout を使用したいと考えています。しかし、私の生活を少し楽にするために、サブクラスで setFrame も使用したいと思います。

要約すると、私の質問は次のとおりです。自動レイアウトを使用して、UIView のフレームをプログラムで調整することはできますか?

4

5 に答える 5

214

はい、これは可能です。

ビューの を設定するとtranslatesAutoresizingMaskIntoConstraints = YES、 への呼び出しsetFrame:は実行時に、ビューの現在の に基づいてレイアウト制約に自動的に変換されますautoresizingMask。これにより、フレームベースのレイアウトと制約ベースのレイアウトを組み合わせることができます。

たとえば、自動レイアウトを使用してビューのすべてのサブビューのレイアウトを定義できますがsetFrame:、ビュー自体のサイズと位置を設定するために呼び出します。あなたの観点からは、自動レイアウトと直接フレーム操作を組み合わせてレイアウトを行っています。しかし、システムは実際には制約を使用してすべてを処理しています。

ただし、 を使用する際には 1 つの大きな注意点がありtranslatesAutoresizingMaskIntoConstraintsます。

これを行う場合でも、これらの自動制約が残りの制約で満たされることを確認する必要があります

たとえば、ビューのサイズと位置を決定する制約が既に存在し、さらに を設定translatesAutoresizingMaskIntoConstraints = YESて呼び出したとしsetFrame:ます。を呼び出すとsetFrame:、ビューに新しい制約が生成されます。これは、既存の制約と競合する可能性があります。

(実際、このエラーは頻繁に発生します。競合する制約に関するログ メッセージが表示され、それらの制約の 1 つが である場合、表示さNSAutoresizingMaskLayoutConstraintれているのは自動制約との競合です。これは簡単な間違いです。なぜなら、translatesAutoresizingMaskIntoConstraints = YESはデフォルト値であるため、コードで制約を構成している場合、これらの自動制約が必要ない場合は忘れずにオフにする必要があります)。

対照的に、ビューのサイズと位置を決定する制約が既に存在しているが、translatesAutoresizingMaskIntoConstraints = NOを呼び出す前に設定したとしますsetFrame:。この場合、setFrame:呼び出しによって新しい制約が生成されないため、個別の制約間の競合は発生しません。ただし、この場合、コンストレイントと設定したフレーム値の間にはまだ「矛盾」があります。次に自動レイアウトが呼び出されると、ビューに既に存在する制約が表示され、必要なフレーム値が計算され、必要な値自体にフレームが設定され、手動で設定した値が上書きされます。

詳細については、Apple のCocoa Auto Layout Guideの「Adopting Auto Layout」セクションを参照してください。

于 2012-11-24T09:01:40.430 に答える
16

私にとって最も簡単な方法は、スーパービューから移動/サイズ変更したいビューを削除し、その を設定してからframe追加し直すことでした。たとえばUILabelUITableViewCellサブクラスのカスタムを取り上げます。

[cell.myLabel removeFromSuperview];
cell.myLabel.frame = someFrameIGenerated;
[cell.contentView addSubview:cell.myLabel];
于 2013-10-30T05:19:46.640 に答える
3

私にとってうまくいったIBOutletのは、ビューコントローラーに制約を追加してからconstant、アウトレットのプロパティを変更することだけでした。

たとえば、ビューの x 原点を変更するには、そのビューの先頭の制約からコントローラーへのアウトレットを設定します。つまり、コンセントを作成します@IBOutlet var labelXOrigin: NSLayoutConstraint!。次に、x位置を調整したいときは、単に次のようにします

self.labelXOrigin.constant = 20.0 // Or whatever origin you want to set.
于 2016-03-20T21:59:11.060 に答える