Angenommen, ich möchte init
eine UIView
-Unterklasse mit einem String
und einem Int
.
Wie würde ich das in Swift wenn ich nur Unterklassen von UIView
mache? Wenn ich nur eine benutzerdefinierte init()
Funktion mache, aber die Parameter sind ein String und Ein Int sagt mir, dass "super.init () nicht vor der Rückkehr vom Initialisierer aufgerufen wird".
Und wenn ich super.init()
aufrufe, muss ich einen dafür vorgesehenen Initialisierer verwenden. Was soll ich dort verwenden? Die Rahmenversion? Die Codiererversion? Beide? Warum?
Die init(frame:)
-Version ist der Standardinitialisierer. Sie müssen es erst aufrufen, nachdem Sie Ihre Instanzvariablen initialisiert haben. Wenn diese Ansicht aus einer Nib wiederhergestellt wird, wird Ihr benutzerdefinierter Initialisierer nicht aufgerufen, sondern die init?(coder:)
-Version. Da Swift jetzt eine Implementierung der erforderlichen init?(coder:)
erfordert, habe ich das folgende Beispiel aktualisiert und die Variablendeklarationen von let
in var
geändert. und optional In diesem Fall würden Sie sie in awakeFromNib()
oder zu einem späteren Zeitpunkt initialisieren.
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)
}
}
Ich erstelle ein gemeinsames Init für das Designierte und Erforderliche. Der Einfachheit halber delegiere ich an init(frame:)
mit dem Frame Null.
Kein Frame zu haben ist kein Problem, da sich die Ansicht normalerweise in der Ansicht eines ViewControllers befindet. Ihre benutzerdefinierte Ansicht erhält eine gute, sichere Chance, ihre Unteransichten zu gestalten, wenn ihre Übersicht layoutSubviews()
oder updateConstraints()
aufruft. Diese beiden Funktionen werden vom System in der Ansichtshierarchie rekursiv aufgerufen. Sie können entweder updateContstraints()
oder layoutSubviews()
verwenden. updateContstraints()
wird zuerst aufgerufen, dann layoutSubviews()
. Stellen Sie in updateConstraints()
sicher, dass Sie super last aufrufen. Rufen Sie in layoutSubviews()
super first auf.
Folgendes mache ich:
@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
}
}
So mache ich das unter iOS 9 in 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"); }
}
Hier ist ein vollständiges Projekt mit Beispiel:
So mache ich eine Unteransicht unter iOS in 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"); }
}