Articles

Benutzerdefinierte UIView-Unterklasse aus einer xib-Datei

Benutzerdefinierte Ansichten mit Ausgängen &Aktionen

Der richtige Weg, um benutzerdefinierte Ansichten aus xib-Dateien zu laden, geht ungefähr so:

Innerhalb Ihres benutzerdefinierten Ansichtsobjekts instanziieren Sie die xib-Datei genau so, wie ich es Ihnen hier oben erklärt habe. 👆 Der einzige Unterschied besteht darin, dass Sie das von den Methoden zurückgegebene Objektarray nicht verwenden müssen, sondern Ihre View-Objekte über den Interface-Builder verbinden müssen, indem Sie den Dateieigentümer als Referenzpunkt verwenden, sowie einen benutzerdefinierten Container-View-Outlet, der alles enthält, was Sie brauchen. 🤨

// note: view object is from my previous tutorial, with autoresizing masks disabledclass CustomView: View { // this is going to be our container object @IBOutlet weak var containerView: UIView! // other usual outlets @IBOutlet weak var textLabel: UILabel! override func initialize() { super.initialize() // first: load the view hierarchy to get proper outlets let name = String(describing: type(of: self)) let nib = UINib(nibName: name, bundle: .main) nib.instantiate(withOwner: self, options: nil) // next: append the container to our view self.addSubview(self.containerView) self.containerView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate() }}

Die Initialisierungsmethode hier lädt also nur die nib-Datei mit dem Eigentümer self. Nachdem der Ladevorgang abgeschlossen ist, werden die Zeiger auf die Ausgänge mit den richtigen Werten aus der xib-Datei gefüllt. Es gibt noch eine letzte Sache, die wir tun müssen. Auch die Ansichten aus der xib-Datei sind „programmatisch“ mit unserem benutzerdefinierten View-Objekt verbunden, aber visuell sind sie es nicht. Wir müssen also unsere Container-View in die View-Hierarchie einfügen. 🤐

Wenn Sie Ihr benutzerdefiniertes View-Objekt verwenden wollen, müssen Sie einfach eine neue Instanz davon erstellen – innerhalb eines View-Controllers – und schließlich können Sie es als Unteransicht hinzufügen!

Ein Wort zu Bounds, Frames aka. Springs und Struts: f*ckng UGLY! Das sind zwei Worte. Sie gelten als schlechte Praxis, also bitte benutze Auto-Layout, ich habe ein nettes Tutorial über Anker, sie sind erstaunlich und lernen sie etwa 15 Minuten. 😅

class ViewController: UIViewController { weak var customView: CustomView! override func loadView() { super.loadView() let customView = CustomView() self.view.addSubview(customView) NSLayoutConstraint.activate() self.customView = customView } override func viewDidLoad() { super.viewDidLoad() self.customView.textLabel.text = "Lorem ipsum" }}

Das war’s, jetzt haben Sie ein vollständig funktionierendes benutzerdefiniertes UIView-Objekt, das eine xib-Datei lädt, um deren Inhalt zu verwenden. War doch gar nicht so schlimm, oder? 🤪

Eine Sache noch. Wenn Sie Ansichten nicht programmatisch behandeln wollen oder einfach nicht mit der loadView-Methode herumspielen wollen, entfernen Sie sie einfach ganz. Als nächstes setzen Sie das @IBOutlet-Schlüsselwort direkt vor Ihre benutzerdefinierte View-Klassenvariable. Öffnen Sie Ihr Storyboard mit IB, dann ziehen Sie & ein neues UIView-Element auf Ihren Controller und verbinden Sie den benutzerdefinierten View-Outlet. Es sollte wie von Zauberhand funktionieren. 💫

In der Überschrift dieses Abschnitts habe ich Outlets und Actions versprochen, also lassen Sie uns ein wenig über IBActions sprechen. Sie funktionieren genau so, wie man es von Controllern erwarten würde. Sie können einfach eine Schaltfläche mit Ihrer benutzerdefinierten Ansicht verknüpfen und die Aktion an die benutzerdefinierte Ansichtsklasse delegieren. Wenn Sie Berührungen oder bestimmte Aktionen an einen Controller weiterleiten wollen, sollten Sie das Delegate-Pattern verwenden oder einen einfachen Block verwenden. 😎