私はカスタム UIView ベースの入力コントロールに取り組んでおり、ビューを設定するための適切な方法を確認しようとしています。UIViewController を操作する場合、およびloadView
関連するviewWill
、viewDid
メソッドを使用するのはかなり簡単ですが、UIView をサブクラス化する場合、最も近いメソッドは`awakeFromNib
、drawRect
、およびlayoutSubviews
です。(セットアップ コールバックとティアダウン コールバックの観点から考えています。) 私の場合は、 でフレームと内部ビューを設定していますlayoutSubviews
が、画面には何も表示されません。
ビューの高さと幅が希望どおりに正しく設定されていることを確認するための最善の方法は何ですか? (私の質問は、自動レイアウトを使用しているかどうかに関係なく適用されますが、答えは 2 つある可能性があります。) 適切な「ベスト プラクティス」は何ですか?
ベストアンサー1
UIView
Apple はドキュメント内でサブクラスの方法をかなり明確に定義しました。
initWithFrame:
以下のリストをチェックしてください。特に、とを見てくださいlayoutSubviews
。前者は のフレームを設定するためのものUIView
で、後者はフレームとそのサブビューのレイアウトを設定するためのものです。
また、プログラムでinitWithFrame:
インスタンス化している場合にのみ呼び出されることを覚えておいてくださいUIView
。nibファイル(またはストーリーボード)からロードしている場合は、initWithCoder:
が使用されます。initWithCoder:
フレームはまだ計算されていないため、Interface Builderで設定したフレームを変更することはできません。提案されているようにこの回答ではフレームを設定するためにinitWithFrame:
から呼び出すことを検討してください。initWithCoder:
UIView
最後に、 nib (またはストーリーボード) からをロードする場合は、が呼び出されると階層内のすべてのビューがアーカイブ解除され、初期化されていることが保証されるawakeFromNib
ため、カスタム フレームとレイアウトの初期化を実行する機会もあります。awakeFromNib
のドキュメントよりNSNibAwaking
(現在はawakeFromNib
):
他のオブジェクトへのメッセージは、awakeFromNib 内から安全に送信できます。その時点で、すべてのオブジェクトがアーカイブ解除され、初期化されていることが保証されます (もちろん、必ずしも起動されるわけではありません)。
また、自動レイアウトでは、ビューのフレームを明示的に設定する必要がないことにも注意してください。代わりに、十分な制約のセットを指定して、レイアウト エンジンによってフレームが自動的に計算されるようにする必要があります。
直接ドキュメンテーション:
オーバーライドするメソッド
初期化
initWithFrame:
このメソッドを実装することをお勧めします。このメソッドに加えて、またはこのメソッドの代わりに、カスタム初期化メソッドを実装することもできます。
initWithCoder:
Interface Builder の nib ファイルからビューをロードし、ビューにカスタム初期化が必要な場合は、このメソッドを実装します。
layerClass
ビューでバッキング ストアに別の Core Animation レイヤーを使用する場合にのみ、このメソッドを実装します。たとえば、OpenGL ES を使用して描画を行う場合は、このメソッドをオーバーライドして CAEAGLLayer クラスを返す必要があります。描画と印刷
drawRect:
ビューがカスタム コンテンツを描画する場合は、このメソッドを実装します。ビューがカスタム描画を行わない場合は、このメソッドをオーバーライドしないでください。
drawRect:forViewPrintFormatter:
印刷中にビューのコンテンツを異なる方法で描画する場合にのみ、このメソッドを実装します。制約
requiresConstraintBasedLayout
ビュー クラスが適切に動作するために制約が必要な場合は、このクラス メソッドを実装します。
updateConstraints
ビューでサブビュー間にカスタム制約を作成する必要がある場合は、このメソッドを実装します。
alignmentRectForFrame:
、frameForAlignmentRect:
これらのメソッドを実装して、ビューを他のビューと揃える方法をオーバーライドします。レイアウト
sizeThatFits:
サイズ変更操作中にビューのデフォルト サイズを通常とは異なるサイズにしたい場合は、このメソッドを実装します。たとえば、このメソッドを使用して、サブビューが正しく表示できないほどビューが縮小されるのを防ぐことができます。
layoutSubviews
制約または自動サイズ変更の動作が提供するよりも、サブビューのレイアウトをより正確に制御する必要がある場合は、このメソッドを実装します。
didAddSubview:
、willRemoveSubview:
サブビューの追加と削除を追跡するには、必要に応じてこれらのメソッドを実装します。
willMoveToSuperview:
、didMoveToSuperview
ビュー階層内の現在のビューの動きを追跡するには、必要に応じてこれらのメソッドを実装します。
willMoveToWindow:
、didMoveToWindow
ビューの別のウィンドウへの移動を追跡するには、必要に応じてこれらのメソッドを実装します。イベント処理:
touchesBegan:withEvent:
、touchesMoved:withEvent:
、touchesEnded:withEvent:
タッチ イベントを直接処理する必要がある場合は、touchesCancelled:withEvent:
これらのメソッドを実装します。(ジェスチャ ベースの入力の場合は、ジェスチャ認識機能を使用します。)
gestureRecognizerShouldBegin:
ビューがタッチ イベントを直接処理し、接続されたジェスチャ認識機能が追加のアクションをトリガーするのを防ぐ必要がある場合は、このメソッドを実装します。