SwiftUI in der Praxis – Teil 2

Sheet modal einblenden

Bei der Arbeit mit dem UIKit-Framework ist es Gang und Gäbe, bestimmte Ansichten als sogenannte modale View einzublenden. Hierbei fährt eine neue View von unten ins Bild hinein und legt sich über die aktuelle Ansicht. Die native Mail-App nutzt dieses Verhalten beispielsweise beim Verfassen einer neuen E-Mail (siehe folgenden Screenshot).

Beim Verfassen einer neuen E-Mail in der nativen Mail-App legt sich die entsprechende View als modale Ansicht über den bestehenden Content.

Dieses Verhalten lässt sich so auch mit SwiftUI umsetzen. Basis hierfür sind verschiedene Modifier, die alle mit dem Schlüsselwort sheet beginnen und auf jede View angewendet werden können. In diesem Artikel möchte ich euch eine Basisvariante dieser Modifier vorstellen, die ich bisher ausschließlich zum Ein- und Ausblenden modaler Ansichten in SwiftUI verwendet habe. Hierbei handelt es sich um die Methode sheet(isPresented:content:).

Sheet ein- und ausblenden

Der Modifier sheet(isPresented:content:) erwartet zwei Parameter. Der erste davon entspricht einem Binding in Form eines Boolean. Es handelt sich hierbei um eine Statusinformation die bestimmt, ob das Sheet sichtbar ist oder nicht (dazu gleich mehr). Der zweite Parameter stellt die View dar, die modal eingeblendet werden soll.

Möchte man also mit SwiftUI eine View modal als Sheet einblenden, ist ein wenig Umdenken erforderlich (aber das gilt ja ganz allgemein für die Arbeit mit SwiftUI). Denn es gibt keine Methode á la presentViewModally(_:), die man aus einem Button heraus aufruft und die dann dafür sorgt, dass die übergebene View angezeigt wird.

Stattdessen erweitert man die View, die eine andere Ansicht modal einblenden soll, mit einem passenden Status. Der wird in der Regel als State-Property umgesetzt und kann einen Namen wie displaysSheet tragen. Standardmäßig ist dieser Status false, was dafür sorgt, dass das Sheet nicht sichtbar ist.

Nun kommt der genannte sheet(isPresented:content:)-Modifier ins Spiel. Den ruft man typischerweise auf der View auf, die für das Ein- und Ausblenden einer modalen View verantwortlich ist. Hierbei übergibt man ihr den eben genannten Status als Binding.

So ist eine View konfiguriert, die über einen Status die Sichtbarkeit eines modalen Sheets steuert und diesen Status mit dem sheet(isPresented:context:)-Modifier verknüpft. Um nun das Sheet einzublenden, braucht es eine Funktion innerhalb der View, die den Status ändert. Das kann im einfachsten Fall ein Button sein, bei dessen Betätigen der aktuelle Wert jenes Status invertiert wird.

Betrachten wir all diese Konzepte einmal anhand eines konkreten Beispiels und fügen so die einzelnen Puzzleteile zu einem großen Ganzen zusammen. Im folgenden Listing wird eine View definiert, die über einen einzigen Button mit dem Text „Present sheet“ verfügt. Bei Betätigen des Buttons wird die State-Property displaysSheet der View invertiert. Jener Status ist mit dem sheet(isPresented:content:)-Modifier verknüpft, der auf dem Button aufgerufen wird. Das hat zur Folge, dass diese View, die in diesem Beispiel nur einen einzelnen Button anzeigt, immer dann ein Sheet einblendet, wenn displaysSheet dem Wert true entspricht. Jenes Sheet wiederum ist eine simple View mit einem Text, der die Info „Modal sheet“ ausgibt.

struct ContentView: View {
    @State private var displaysSheet = false
    
    var body: some View {
        Button(action: {
            self.displaysSheet.toggle()
        }) {
            Text("Present sheet")
                .font(.largeTitle)
        }
        .sheet(isPresented: $displaysSheet) {
            Text("Modal sheet")
        }
    }
}

Übrigens: Ein eingeblendetes Sheet lässt sich unter iOS schlicht durch eine Swipe-Geste von oben nach unten wieder ausblenden. Hierbei setzt das System automatisch den dem sheet(isPresentend:content:)-Modifier zugewiesenen Status zurück auf false.

Mithilfe eines Status steuert man die Sichtbarkeit einer modal eingeblendeten View.

Fazit

Das Ein- und Ausblenden modaler Ansichten erfordert ein Umdenken in SwiftUI. Statt eines imperativen Methodenaufrufs, der die View einblendet, bestimmt nun ein deklarativer Status, ob eine Ansicht modal eingeblendet wird oder nicht. Ändert sich der Status, ändert sich auch entsprechend die Darstellung.

Euer Thomas

Bisherige Artikel in dieser Serie


Kommentare

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

  1. Avatar von Mario Wolfgang Antonino
    Mario Wolfgang Antonino

    Kann man mit diesem Konzept auch die Tastatur (die beim Antippen eines Textfeldes erscheint) mit z.B: einem Button beliebig ein- und ausblenden ?

    1. Soweit ich bisher weiß, gibt es keine vergleichbare Funktion bzw. einen Status für das Ein- und Ausblenden der Bildschirmtastatur. Hier muss man in iOS den Weg über die Responder Chain gehen, die intern auch bei TextField greift (selbst wenn TextField nicht Teil des UIKit-Frameworks ist).

      Ein einfaches Beispiel, wie eine solche Umsetzung aussehen kann, findest du im folgenden Listing. Darin habe ich zusätzlich eine Extension für UIApplication erstellt, um den aktuellen First Responder aufzuheben. Diese Funktion ist mit einem Button gekoppelt, bei dessen Betätigen nun immer die Bildschirmtastatur automatisch ausgeblendet wird.

      struct ContentView: View {
          @State private var textFieldValue = ""
          
          var body: some View {
              VStack {
                  TextField("Placeholder", text: $textFieldValue)
                  Button(action: {
                      UIApplication.shared.endEditing()
                  }) {
                      Text("Hide keyboard")
                  }
                  Spacer()
              }
              .padding()
          }
      }
      
      extension UIApplication {
          func endEditing() {
              sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
          }
      }

      Ich hoffe ich konnte dir damit weiterhelfen, lass es mich wissen falls noch Fragen offen sind! Tatsächlich ist das auch ein spannendes Thema für einen eigenen Artikel hier auf dem Blog. 😉

      1. Avatar von Mario Wolfgang Antonino
        Mario Wolfgang Antonino

        Whow – es funktioniert, vielen Dank – ich hab keine Ahnung warum, aber es funktioniert ! 🤗

Schreibe einen Kommentar

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