SwiftUI in der Praxis – Teil 8

Eigene Modifier erstellen

Mithilfe von Modifiern führt man Anpassungen an Views in SwiftUI durch. Mit ihnen lässt sich Text formatieren, die Größe eines Bildes anpassen oder eine Hintergrundfarbe setzen.

Das SwiftUI-Framework bringt bereits von Haus aus eine riesige Zahl an solchen Modifiern mit. Nichtsdestotrotz wäre es in manchen Fällen praktisch, eigene Modifier zu erzeugen. Die würden sich typischerweise aus der Kombination verschiedener bestehender Modifier zusammensetzen und daraus einen gänzlich neuen Modifier generieren.

Erfreulicherweise lassen sich solche eigenen Modifier tatsächlich dank des ViewModifier-Protokolls realisieren. Dieses Protokoll besitzt eine einzige Anforderung in Form der Methode body(content:). Als Parameter liefert diese Methode eine bestehende View und erwartet als Ergebnis eine neue View. Das kann man nutzen, um die mittels Parameter erhaltene View so zu konfigurieren, wie man möchte, und aus dem Ergebnis eine neue View zu erstellen.

Ein Beispiel zum Einsatz des ViewModifier-Protkolls findet ihr im folgenden Listing. Darin erfolgt die Erstellung einer Structure namens CustomTitle, die konform zum genannten ViewModifier-Protokoll ist. Entsprechend implementiert die Structure die Methode body(content:). Der content-Parameter entspricht der View, die diesen Modifier aufruft, und die wird entsprechend angepasst. Zur Anpassung gehören hierbei das Setzen von Abständen mittels padding(), das Verändern der Größe sowie das Setzen von Farben und einem Rahmen.

struct CustomTitle: ViewModifier {
    func body(content: Content) -> some View {
        content
            .padding()
            .font(.largeTitle)
            .foregroundColor(.blue)
            .background(Color.yellow)
            .border(Color.blue, width: 0.5)
    }
}

Um nun einen solch eigens erzeugten Modifier einzusetzen, nutzt man wiederum einen Modifier aus SwiftUI namens modifier(_:). Den ruft man auf die gewünschte View auf und übergibt als Parameter eine Instanz des zum ViewModifier-Protokoll konformen Typs, der für die Anpassung der View verwendet werden soll – in diesem Beispiel also eine Instanz von CustomTitle.

Das folgende Listing zeigt euch auch hierzu ein Beispiel. Darin wird eine Text-Instanz mithilfe des eben von uns selbst definierten Modifiers angepasst.

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .modifier(CustomTitle())
    }
}
Diese Text-View wurde mithilfe eines eigens kreierten Modifiers angepasst.
Diese Text-View wurde mithilfe eines eigens kreierten Modifiers angepasst.

Vorteile und Optimierungen

Das Erstellen eigener Modifier mithilfe des ViewModifier-Protokolls ist ideal, wenn man mehrere Views auf immer die gleiche Art und Weise (sprich durch Einsatz der immer gleichen Modifier) konfiguriert. Die entsprechenden Anpassungen lassen sich so in einen eigenen Typ packen und an jeder beliebigen Stelle durch Einsatz der modifier(_:)-Methode verwenden. Das kann auch dazu beitragen, den eigenen Quellcode übersichtlicher zu gestalten und eigene Layouts an zentralen Stellen zu definieren.

Der Einsatz eigener Modifier lässt sich darüber hinaus aber noch weiter optimieren. Gerade wenn man mehrere davon einsetzt, kann der häufige Aufruf der modifier(_:)-Methode nämlich durchaus etwas unübersichtlich wirken. Generell passt er auch nicht so gut zu den typischen Modifier-Aufrufen wie bold() oder font(_:).

Um das zu ändern, kann man einfach eine Extension des View-Protokolls erstellen und darin eine eigene Methode unterbringen, die den gewünschten Modifier auf self aufruft. Das erlaubt es, dieser Methode (die so gesehen dann eigentlich selbst ein Modifier ist, da sie ja einen eigens kreierten Modifier aufruft) einen beliebigen passenden Namen zu geben und den beim Einsatz des Modifiers zu verwenden.

Wie so etwas aussehen kann, zeigt beispielhaft das folgende Listing. Das View-Protokoll wird darin um eine neue Methode namens customTitle() ergänzt. Diese Methode soll als Modifier für unsere CustomTitle-Structure dienen. Entsprechend rufen wir auf der zugrundeliegenden View, die wir mittels self referenzieren, die modifier(_:)-Methode wie zuvor auf und übergeben die gewünschte CustomTitle-Instanz.

Nun lässt sich aus jeder View heraus die neue customTitle()-Methode direkt aufrufen, die unserem eigens erstellten Modifier entspricht. Das Ergebnis ist dasselbe wie zuvor.

extension View {
    func customTitle() -> some View {
        self.modifier(CustomTitle())
    }
}

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .customTitle()
    }
}

Fazit

Die Möglichkeit, eigene Modifier zum Einsatz in SwiftUI zu erstellen, erlaubt an geeigneten Stellen eine massive Optimierung des Quellcodes. Mithilfe einer View-Extension lassen sich solche Modifier zudem auf die gleiche Art und Weise einsetzen, wie man es bereits von den in SwiftUI mitgelieferten Modifiern her kennt und gewohnt ist.

Euer Thomas

Bisherige Artikel in dieser Serie


Kommentare

2 Antworten zu „SwiftUI in der Praxis – Teil 8“

  1. Kann man modifier überschreiben, das heisst kann man neue oder andere funktionalität an ein swift-standard modifier geben ?

    1. Meines Wissens nach ist das nicht möglich. Das hängt vor allen Dingen damit zusammen, dass die Standard-Modifier als Teil der verschiedenen Views implementiert sind. So bringen Typen wie Text, Image oder List alle ihre eigene Implementierung der Standard-Modifier mit. Da es sich bei diesen Typen aber um Structures handelt und die nicht überschrieben werden können, sehe ich keine Möglichkeit, die Standard-Modifier zu verändern. Falls mir aber noch etwas anderes dazu einfallen sollte lasse ich es dich wissen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert