回答:
init(frame:)
バージョンは、デフォルトの初期化子です。インスタンス変数を初期化した後でのみ呼び出す必要があります。このビューがNibから再構成されている場合、カスタム初期化子は呼び出されず、代わりにinit?(coder:)
バージョンが呼び出されます。Swiftはrequiredの実装を必要とするようになったため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)
}
}
init(coder:)
。
s
、i
ここでは物事をシンプルに保つためのオプション。オプションでなかった場合は、必要なイニシャライザで初期化する必要もあります。それらをオプションにすることはnil
、super.init()
が呼び出されたときにそれらが存在することを意味します。それらがオプションでなければ、super.init()を呼び出す前に割り当てる必要があります。
指定された必須の共通initを作成します。便宜上、私init(frame:)
はフレーム0で委任します。
フレームがゼロであっても問題はありません。通常、ビューはViewControllerのビュー内にあるためです。カスタムビューは、スーパービューがlayoutSubviews()
またはを呼び出したときに、サブビューをレイアウトするための適切で安全な機会を得ますupdateConstraints()
。これらの2つの関数は、ビュー階層全体でシステムによって再帰的に呼び出されます。updateContstraints()
またはを使用できますlayoutSubviews()
。updateContstraints()
が最初に呼び出され、次にが呼び出されlayoutSubviews()
ます。でupdateConstraints()
確認してくださいスーパー呼び出すことが最後。ではlayoutSubviews()
、最初に superを呼び出します。
これが私がすることです:
@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
}
}
commonInit
メソッド内のいくつかのプロパティを初期化したいがsuper
、この場合、それを配置することはできませんsuper
。呼び出しの前にすべてのプロパティを初期化する必要があるためです。笑デッドループのようです。
これが私がSwiftのiOS 9でそれを行う方法です-
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"); }
}
ここに例を含む完全なプロジェクトがあります:
super.init
にカスタマイズを行うということですが、彼はそれを前に行う必要があると述べましたsuper.init
...
これがSwiftのiOSでサブビューを行う方法です-
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"); }
}
var
。しかし、Swiftのデフォルトのベストプラクティスlet
は、変数を宣言する理由がない限り、変数を宣言することvar
です。上記の私のコード例では、そうする理由はありませんでしたlet
。