import SwiftUI
struct ImageLoaderView: View {
@State private var image: UIImage? = nil
@State private var isLoading = false
@State private var errorMessage: String? = nil
let imageUrl = URL(string: "https://picsum.photos/300")!
var body: some View {
VStack(spacing: 20) {
if let uiImage = image {
Image(uiImage: uiImage)
.resizable()
.scaledToFit()
.frame(maxWidth: 300, maxHeight: 300)
.cornerRadius(8)
.accessibilityLabel(Text("Loaded image from internet"))
} else if isLoading {
Image(systemName: "photo")
.resizable()
.scaledToFit()
.frame(width: 100, height: 100)
.foregroundColor(.gray)
.accessibilityHidden(true)
Text("Loading image...")
.accessibilityLabel(Text("Loading image"))
} else if let error = errorMessage {
Image(systemName: "exclamationmark.triangle")
.resizable()
.scaledToFit()
.frame(width: 80, height: 80)
.foregroundColor(.red)
.accessibilityHidden(true)
Text(error)
.foregroundColor(.red)
.accessibilityLabel(Text("Error loading image"))
} else {
Image(systemName: "photo")
.resizable()
.scaledToFit()
.frame(width: 100, height: 100)
.foregroundColor(.gray)
.accessibilityHidden(true)
Text("No image loaded")
.accessibilityLabel(Text("No image loaded"))
}
Button("Reload") {
loadImage()
}
.padding()
.accessibilityLabel(Text("Reload image button"))
}
.padding()
.onAppear {
loadImage()
}
}
func loadImage() {
isLoading = true
errorMessage = nil
image = nil
let task = URLSession.shared.dataTask(with: imageUrl) { data, response, error in
DispatchQueue.main.async {
isLoading = false
if let error = error {
errorMessage = "Failed to load image: \(error.localizedDescription)"
return
}
guard let data = data, let uiImage = UIImage(data: data) else {
errorMessage = "Invalid image data"
return
}
image = uiImage
}
}
task.resume()
}
}
struct ImageLoaderView_Previews: PreviewProvider {
static var previews: some View {
ImageLoaderView()
}
}This SwiftUI view uses @State variables to track the image, loading state, and error message. When the view appears, it calls loadImage() which starts a URLSession data task to fetch the image data from the URL.
While loading, it shows a placeholder system image and a loading text. If loading fails, it shows an error icon and message. When the image loads successfully, it displays the image with a nice corner radius.
The Reload button calls loadImage() again to retry loading the image. Accessibility labels are added for screen readers. The UI is simple and responsive, showing clear states for loading, success, and error.