Views austauschen ohne Navigation in SwiftUI


Die Navigation von einer View zu einer anderen war lange Zeit die einzige leichte Möglichkeit, in einer App unterschiedliche grafische Oberflächen anzuzeigen. Eine View wurde während der Entwicklung in einem Storyboard oder in einer XIB-Datei hinterlegt und war somit mehr oder weniger statisch im Programm vorhanden. Sollte in einem laufenden Programm ein Teil einer View verändert werden, war das keine triviale Aufgabe. Einfacher wurde es für Entwickler erst mit der Einführung von SwiftUI. Dort ist es kein Problem mehr, die angezeigte grafische Oberfläche zu verändern oder auszutauschen, ohne die aktuelle View zu verlassen. Die Umsetzung ist so einfach, dass eine if-Anweisung oder eine switch-case ausreicht, um verschiedene Inhalte anzuzeigen. In der Theorie etwa so:

Zeige Inhalt A an oder zeige Inhalt B an.

Etwas aufwändiger ist die Realität dann aber doch. Weil die body-Eigenschaft eines SwiftUI-View immer nur genau eine View zurückgeben kann, funktioniert es nicht, die if-Anweisung direkt in die Eigenschaft zu schreiben. Sie muss einer Group untergeordnet sein. Anschließen können, in Abhängigkeit von einer Bedienung, verschiedene Views aus der Eigenschaft zurückgeben. Wie das prinzipiell funktionieren kann, zeigt das folgende Listing.

struct ContentViewView {

    

    @State var showContentTypeA = false

    

    var bodysome View {

       Group {

            if showContentTypeA {

                Text("Content A")

                    .font(.largeTitle)

            }

            else {

                Text("Content B")

                    .font(.largeTitle)

            }

        }

    }

}

Übersichtlicher und leichter zu bearbeiten ist der Code, nachdem die beiden alternativen Inhalte in eigenständige View-Strukturen ausgelagert wurden. Dann wäre es sogar möglich, diese in einzelnen Dateien zu speichern. Ideal für eine erneute Verwendung in anderen Projekten. Sämtliche View in eine Datei zu schreiben, funktioniert aber ebenfalls.

// Ein View  für den Inhalt Typ A

struct ContentAViewView {

    var bodysome View {

        Text("Content A")

            .font(.largeTitle)

    }

}


// Ein View  für den Inhalt Typ B

struct ContentBViewView {

    var bodysome View {

        Text("Content B")

            .font(.largeTitle)

    }

}


// Der übergeordnete View zeigt den Inhalt A oder B an

struct ContentViewView {

    

    @State var showContentTypeA = false

    

    var bodysome View {

        Group {

            if showContentTypeA {

                ContentAView()

            }

            else {

                ContentBView()

            }

        }

    }

}

Welcher der beiden SubView zur Anzeige kommt, wird im Programm von der Variablen showContentTypeA gesteuert. Bisher ist ihr Wert unveränderlich im Programmcode hinterlegt und kann vom Anwender nicht beeinflußt werden. Im nächsten Listing wird die Variable über @Binding an beide SubView übergeben. Zusätzlich erhält jede View einen Button, mit dem zu der jeweils anderen Ansicht umgeschaltet werden kann. Soll zwischen mehr als zwei Ansichten gewechselt werden, sollte anstelle des Bool-Typen ein enum zum Einsatz kommen.

// Ein View  für den Inhalt Typ A

struct ContentAViewView {

    

    @Binding var showContentTypeA : Bool

    

    var bodysome View {

        VStack{

        Text("Content A")

            .font(.largeTitle)

            Button("Switch View", action: { self.showContentTypeA = false })

        }

    }

}


// Ein View  für den Inhalt Typ B

struct ContentBViewView {

    

    @Binding var showContentTypeA : Bool

    

    var bodysome View {

        VStack{

        Text("Content B")

            .font(.largeTitle)

            Button("Switch View", action: { self.showContentTypeA = true })

        }

    }

}


// Der übergeordnete View zeigt den Inhalt A oder B an

struct ContentViewView {

    

    @State var showContentTypeA = true

    

    var bodysome View {

        Group {

            if showContentTypeA {

                ContentAView(showContentTypeA: $showContentTypeA)

            }

            else {

                ContentBView(showContentTypeA: $showContentTypeA)

            }

        }

    }

}


Geschrieben am: 01.06.2020
Technologien: Swift, SwiftUI, macOS, iOS