web-dev-qa-db-ja.com

SwiftのUIViewサブクラスのカスタムinitを作成するにはどうすればよいですか?

initUIViewを持つStringサブクラスをIntにしたいとします。

UIViewをサブクラス化するだけの場合、Swiftでこれを行うにはどうすればよいですか?カスタムinit()関数を作成するだけで、パラメーターがStringおよびIntである場合、「イニシャライザーから戻る前にsuper.init()が呼び出されない」と表示されます。

そして、super.init()を呼び出すと、指定された初期化子を使用する必要があると言われます。そこで何を使うべきですか?フレームバージョン?コーダーのバージョン?両方?どうして?

106
Doug Smith

init(frame:)バージョンはデフォルトの初期化子です。インスタンス変数を初期化した後にのみ呼び出す必要があります。このビューがNibから再構成されている場合、カスタム初期化子は呼び出されず、代わりにinit?(coder:)バージョンが呼び出されます。 Swiftには必須のinit?(coder:)の実装が必要になったため、以下の例を更新し、let変数宣言をvarおよびオプションに変更しました。この場合、awakeFromNib()で初期化するか、しばらくしてから初期化します。

class TestView : UIView {
    var s: String?
    var i: Int?
    init(s: String, i: Int) {
        self.s = s
        self.i = i
        super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}
173
Wolf McNally

指定および必須の共通の初期化を作成します。便宜上、ゼロのフレームでinit(frame:)に委任します。

通常、ビューはViewControllerのビュー内にあるため、フレームがゼロであっても問題はありません。カスタムビューは、スーパービューがlayoutSubviews()またはupdateConstraints()を呼び出したときに、サブビューをレイアウトするための適切で安全な機会を得ます。これらの2つの関数は、ビュー階層全体でシステムによって再帰的に呼び出されます。 updateContstraints()またはlayoutSubviews()のいずれかを使用できます。 updateContstraints()が最初に呼び出され、次にlayoutSubviews()が呼び出されます。 updateConstraints()で、必ずsuper lastを呼び出してください。 layoutSubviews()で、super firstを呼び出します。

ここに私がやることがあります:

@IBDesignable
class MyView: UIView {

      convenience init(args: Whatever) {
          self.init(frame: CGRect.zero)
          //assign custom vars
      }

      override init(frame: CGRect) {
           super.init(frame: frame)
           commonInit()
      }

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

      override func prepareForInterfaceBuilder() {
           super.prepareForInterfaceBuilder()
           commonInit()
      }

      private func commonInit() {
           //custom initialization
      }

      override func updateConstraints() {
           //set subview constraints here
           super.updateConstraints()
      }

      override func layoutSubviews() {
           super.layoutSubviews()
           //manually set subview frames here
      }

}
18
MH175

IOS 9でSwiftで行う方法は次のとおりです-

import UIKit

class CustomView : UIView {

    init() {
        super.init(frame: UIScreen.mainScreen().bounds);

        //for debug validation
        self.backgroundColor = UIColor.blueColor();
        print("My Custom Init");

        return;
    }

    required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented"); }
}

以下に完全なプロジェクトの例を示します。

17
J-Dizzle

IOSでSwiftでサブビューを行う方法は次のとおりです-

class CustomSubview : UIView {

    init() {
        super.init(frame: UIScreen.mainScreen().bounds);

        let windowHeight : CGFloat = 150;
        let windowWidth  : CGFloat = 360;

        self.backgroundColor = UIColor.whiteColor();
        self.frame = CGRectMake(0, 0, windowWidth, windowHeight);
        self.center = CGPoint(x: UIScreen.mainScreen().bounds.width/2, y: 375);

        //for debug validation
        self.backgroundColor = UIColor.grayColor();
        print("My Custom Init");

        return;
    }

    required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented"); }
}
9
J-Dizzle