Zum Inhalt springen

AsyncImage unterstützt .resizable() nicht

SwiftUI's AsyncImage erlaubt den .resizable()-Modifier nicht, was einen phasenbasierten Workaround erfordert.

Das Problem

SwiftUI’s AsyncImage ist praktisch zum Laden von Remote-Bildern, hat aber eine überraschende Einschränkung: Du kannst den .resizable()-Modifier nicht darauf anwenden. Dieser Code kompiliert, verhält sich aber nicht wie erwartet:

// This does NOT work as intended
AsyncImage(url: imageURL)
   .resizable()  // Has no effect -- AsyncImage is not an Image
   .aspectRatio(contentMode: .fill)
   .frame(width: 200, height: 200)

Der Grund ist, dass AsyncImage kein Image ist – es ist eine Container-View, die den Ladezustand verwaltet. Der .resizable()-Modifier ist nur auf Image definiert, sodass die Anwendung auf AsyncImage nur die generische View-Version aufruft, die nichts Nützliches tut.

Die Lösung

Die Lösung ist die Verwendung des phasenbasierten Initializers, der dir direkten Zugriff auf den zugrunde liegenden Image-Wert gibt, sobald das Laden abgeschlossen ist:

AsyncImage(url: imageURL) { phase in
   switch phase {
   case .success(let image):
      image
         .resizable()
         .aspectRatio(contentMode: .fill)
   case .failure:
      Image(systemName: "photo")
         .foregroundStyle(.secondary)
   case .empty:
      ProgressView()
   @unknown default:
      EmptyView()
   }
}
.frame(width: 200, height: 200)
.clipped()

Innerhalb des .success-Falls ist image ein echter Image-Wert, sodass .resizable() korrekt funktioniert. Das gibt dir auch Kontrolle über die Lade- und Fehlerzustände, was ohnehin die bessere Praxis ist.

Wann man manuell lädt

Wenn du die rohen Bilddaten brauchst – zum Beispiel um sie zu cachen, ihre Größe zu prüfen oder ein UIImage zu erstellen – möchtest du AsyncImage vielleicht ganz überspringen und mit URLSession laden. Aber für die meisten reinen Anzeigefälle deckt der phasenbasierte Initializer den Bedarf ohne zusätzliche Komplexität.

Das ist eine dieser SwiftUI-APIs, bei denen der einfache Initializer verlockend aussieht, aber in der Praxis zu kurz greift. Verwende standardmäßig die phasenbasierte Version, wann immer du bildspezifische Modifier brauchst.

War das hilfreich? Folge mir auf Bluesky und Mastodon für mehr Swift-Tipps und Indie-Dev-Updates.