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 ContentView: View {
@State var showContentTypeA = false
var body: some 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 ContentAView: View {
var body: some View {
Text("Content A")
.font(.largeTitle)
}
}
// Ein View für den Inhalt Typ B
struct ContentBView: View {
var body: some View {
Text("Content B")
.font(.largeTitle)
}
}
// Der übergeordnete View zeigt den Inhalt A oder B an
struct ContentView: View {
@State var showContentTypeA = false
var body: some 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 ContentAView: View {
@Binding var showContentTypeA : Bool
var body: some View {
VStack{
Text("Content A")
.font(.largeTitle)
Button("Switch View", action: { self.showContentTypeA = false })
}
}
}
// Ein View für den Inhalt Typ B
struct ContentBView: View {
@Binding var showContentTypeA : Bool
var body: some 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 ContentView: View {
@State var showContentTypeA = true
var body: some View {
Group {
if showContentTypeA {
ContentAView(showContentTypeA: $showContentTypeA)
}
else {
ContentBView(showContentTypeA: $showContentTypeA)
}
}
}
}
Geschrieben am: 01.06.2020 Technologien: Swift, SwiftUI, macOS, iOS