Sorun
SwiftUI’ın AsyncImage‘ı uzak görselleri yüklemek için kullanışlı, ama şaşırtıcı bir sınırlaması var: .resizable() modifier’ını uygulayamıyorsun. Bu kod derleniyor ama beklendiği gibi çalışmıyor:
// 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)Nedeni, AsyncImage‘ın bir Image olmaması – yükleme durumunu yöneten bir konteyner view. .resizable() modifier’ı sadece Image üzerinde tanımlı, bu yüzden onu AsyncImage’a uygulamak sadece genel View versiyonunu çağırıyor ki o da işe yaramıyor.
Çözüm
Çözüm, yükleme tamamlandıktan sonra alttaki Image değerine doğrudan erişim sağlayan phase tabanlı başlatıcıyı kullanmak:
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().success durumunun içinde, image gerçek bir Image değeri, bu yüzden .resizable() doğru çalışıyor. Bu ayrıca yükleme ve hata durumları üzerinde kontrol sağlıyor ki bu zaten daha iyi bir uygulama.
Ne Zaman Manuel Yüklenir
Ham görsel verisine ihtiyacın varsa – örneğin önbelleğe almak, boyutunu incelemek veya bir UIImage oluşturmak için – AsyncImage’ı tamamen atlayıp URLSession ile yüklemek isteyebilirsin. Ama çoğu sadece görüntüleme amaçlı durum için, phase tabanlı başlatıcı ekstra karmaşıklık olmadan ihtiyacı karşılıyor.
Bu, basit başlatıcının çekici göründüğü ama pratikte yetersiz kaldığı SwiftUI API’lerinden biri. Görsel-özel modifier’lara ihtiyacın olduğunda varsayılan olarak phase tabanlı versiyonu kullan.
