168

私はいくつかのカスタム UIView ベースの入力コントロールに取り組んでおり、ビューを設定するための適切な方法を確認しようとしています。UIViewController を操作する場合、loadViewおよび 関連するviewWillviewDidメソッドを使用するのはかなり簡単ですが、UIView をサブクラス化する場合、私が持っている最も近いメソッドは`awakeFromNibdrawRect、およびlayoutSubviewsです。(セットアップとティアダウンのコールバックの観点から考えています。) 私の場合、フレームと内部ビューを でセットアップしていますがlayoutSubviews、画面に何も表示されません。

ビューの高さと幅が正しいことを確認する最善の方法は何ですか? (自動レイアウトを使用しているかどうかに関係なく、2 つの答えがあるかもしれませんが、私の質問は当てはまります。) 適切な「ベスト プラクティス」は何ですか?

4

4 に答える 4

41

これはまだGoogleで高く評価されています。以下は、swift の更新された例です。

このdidLoad関数を使用すると、すべてのカスタム初期化コードを配置できます。他の人が述べたように、didLoadプログラムでビューが作成されたinit(frame:)とき、またはXIBデシリアライザーがXIBテンプレートをビューにマージしたときに呼び出されますinit(coder:)

余談: layoutSubviewsandupdateConstraintsは、ほとんどのビューで複数回呼び出されます。これは、ビューの境界が変更されたときの高度なマルチパス レイアウトと調整を目的としています。個人的には、可能な限りマルチパス レイアウトを避けています。CPU サイクルを消費し、すべてが頭痛の種になるからです。さらに、イニシャライザを無効にすることはめったにないので、イニシャライザ自体に制約コードを入れています。

import UIKit

class MyView: UIView {
  //-----------------------------------------------------------------------------------------------------
  //Constructors, Initializers, and UIView lifecycle
  //-----------------------------------------------------------------------------------------------------
  override init(frame: CGRect) {
      super.init(frame: frame)
      didLoad()
  }

  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    didLoad()
  }

  convenience init() {
    self.init(frame: CGRectZero)
  }

  func didLoad() {
    //Place your initialization code here

    //I actually create & place constraints in here, instead of in
    //updateConstraints
  }

  override func layoutSubviews() {
     super.layoutSubviews()

     //Custom manually positioning layout goes here (auto-layout pass has already run first pass)
  }

  override func updateConstraints() {
    super.updateConstraints()

    //Disable this if you are adding constraints manually
    //or you're going to have a 'bad time'
    //self.translatesAutoresizingMaskIntoConstraints = false

    //Add custom constraint code here
  }
}
于 2015-11-15T15:54:22.447 に答える
14

Apple のドキュメントに適切な要約があり、これはiTunes で利用できる無料のスタンフォード コースで詳しく説明されています。TL;DR バージョンをここに示します。

クラスの大部分がサブビューで構成されている場合、サブビューを割り当てる適切な場所はinitメソッドです。initビューの場合、ビューがコードからインスタンス化されているか、ペン先/ストーリーボードからインスタンス化されているかに応じて、呼び出される可能性のある 2 つの異なるメソッドがあります。私がしていることは、独自のメソッドを作成し、とメソッドsetupの両方から呼び出すことです。initWithFrame:initWithCoder:

カスタム描画を行っている場合は、実際にdrawRect:ビューでオーバーライドする必要があります。ただし、カスタム ビューのほとんどがサブビューのコンテナーである場合は、おそらくその必要はありません。

layoutSubViews縦向きか横向きかによって、サブビューを追加または削除するようなことをしたい場合にのみオーバーライドしてください。それ以外の場合は、放っておくことができるはずです。

于 2013-04-12T18:59:50.793 に答える