I want a balloon fly from bottom to top forever. Every fly the X start and duratoin is different.
In the first version, Balloon images were in a folder under the project. I made sure the load is good (‘Image(uiImage: uiImage)’), as i have checked the image render well. however, using withAnimation only cause fade in/out, but not move. Then i added a boarder to the image, and interesting, the image itself still fade in/out, but the boarder were flying….
In the seconde version, Balloon image are load from assets, and everything works well.
Here’s the code
struct BalloonView: View {
@State private var balloonX: CGFloat = UIScreen.main.bounds.width / 2
@State private var balloonY: CGFloat = 0
private let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
Image("ballon-blue-muti") // works well
// BalloonView.loadAirBalloons()[0] // Image are fade in/out, but board works
.resizable()
.scaledToFit()
.frame(width: 50)
.border(.black)
.position(x: balloonX, y: balloonY)
.onAppear {
startBalloonAnimation(screenHeight: UIScreen.main.bounds.height)
}
.onReceive(timer) { _ in
print("balloonX: \(balloonX), balloonY: \(balloonY)")
}
}
private func startBalloonAnimation(screenHeight: CGFloat) {
let screenWidth = UIScreen.main.bounds.width
balloonX = CGFloat.random(in: 0...screenWidth)
balloonY = screenHeight
let duration = Double.random(in: 5...10)
let endX = CGFloat.random(in: 0...screenWidth)
withAnimation(Animation.linear(duration: duration)) {
balloonY = screenHeight / 2
balloonX = endX
}
DispatchQueue.main.asyncAfter(deadline: .now() + duration) {
balloonY = screenHeight
startBalloonAnimation(screenHeight: screenHeight)
}
}
static private func loadAirBalloons() -> [Image] {
if let path = Bundle.main.resourcePath {
let imageFolder = path.appending("/images/balloons")
do {
let fileNames = try FileManager.default.contentsOfDirectory(atPath: imageFolder)
return fileNames.compactMap { fileName in
if let uiImage = UIImage(contentsOfFile: "\(imageFolder)/\(fileName)") {
return Image(uiImage: uiImage)
}
return nil
}
} catch {
print(error)
}
}
return []
}
}
struct Background: View {
var body: some View {
ZStack {
BalloonView()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.pink)
}
}
i use folder because I don’t want to add new code when i add new images…Seems only bundle works for this.
So if still using Image(uiImage: uiImage) approach, how to fix it?
And why there’s different?
As I wrote, I load image from assets instead of Image(uiImage: uiImage)




