wake-up-neo.com

Wie schreibe ich ein benutzerdefiniertes Init für eine UIView-Unterklasse in Swift?

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?

108
Doug Smith

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)
    }
}
175
Wolf McNally

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
      }

}
22
MH175

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:

17
J-Dizzle

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"); }
}
9
J-Dizzle