I am building a rather long quiz app. Some questions have images and others don't. All the images are locally stored. I want to dynamically show an image if it exists in the local assets catalog. For those questions that do not have an image, I would like the question text to occupy the space on the screen where the image would be. Whenever I add .resizable() to the image, I get an ugly space even when SwiftUI finds no image.
import SwiftUI
struct Question {
var text: String
}
struct ContentView: View {
@State var questionNumber = 0
var questions = [
Question(text: "Question 0 has an image in the assets folder"),
Question(text: "No image for Question 1 in the assets folder"),
]
var body: some View {
VStack {
VStack {
//I have an image named 0 in the assets folder
Image("\(questionNumber)").resizable().scaledToFit()
Text("\(questions[questionNumber].text)")
}
.padding()
Spacer()
HStack {
Button {
questionNumber = 0
} label: {
Text("Question 0")
}
Button {
questionNumber = 1
} label: {
Text("Question 1")
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
You can use UIImage
or NSImage
(macOS) to check if the image exists. If UIImage(named:)
returns nil
, the image doesn't exist.
extension View {
func isImageExist(_ imageName: String) -> Bool {
#if canImport(AppKit)
return (NSImage(named: imageName) != nil)
#elseif canImport(UIKit)
return (UIImage(named: imageName) != nil)
#endif
}
}
Use:
VStack {
if isImageExist("\(questionNumber)") {
Image("\(questionNumber)").resizable().scaledToFit()
}
Text("Hello, world!")
}
.padding()