[英]Crossfading Images in SwiftUI doesn't seem to work
我想實現一個動畫背景,在 SwiftUI 中對一堆圖像進行淡入淡出。
我已經使用以下代碼片段設法使一組顏色在它們之間很好地交叉淡入淡出,但是如果我用一組圖像替換顏色數組,則相同的方法不起作用。 圖像被替換,但沒有動畫。 然而 Color 和 Image 都屬於 some View 類型,對嗎?
以下工作:
struct ImageBackgroundView: View {
@State private var index = 0
private let colors:[Color] = [.red, .blue, .green, .orange, .pink, .black]
private let timer = Timer.publish(every: 5, on: .main, in: .common).autoconnect()
var body: some View {
colors[self.index]
.animation(.easeInOut(duration: 1))
.onReceive(timer) { _ in
print(self.index)
self.index += 1
if self.index > 5 { self.index = 0 }
}
}
但是,如果我用 [Images] 類型的數組替換 [Color] 數組,如下所示,圖像會轉換,但交叉淡入淡出似乎不起作用:
struct ImageBackgroundView: View {
@State private var index = 0
private let images = (1...8).map { Image("background\($0)") }
private let timer = Timer.publish(every: 5, on: .main, in: .common).autoconnect()
var body: some View {
images[self.index]
.animation(.easeInOut(duration: 1))
.onReceive(timer) { _ in
print(self.index)
self.index += 1
if self.index > 5 { self.index = 0 }
}
}
任何人都可以解釋為什么會這樣嗎? 目前這只是 SwiftUI 中的一個錯誤嗎?
我在以前的應用程序中使用各種 addSubview 調用實現了類似的效果,這些調用為覆蓋視圖的不透明度設置動畫——在這個勇敢的新 SwiftUI 世界中,我們不需要擺弄各種東西,對吧?
這很有趣,它讓我思考。
您可以使用標志,例如show
。 還有一個ZStack
保存你的image
對象。 然后在該image
使用transition
與您想要的animation
相結合。
但是,只有在show
為true
時才這樣做。
將.onReceive
事件附加到ZStack
而不是您的image
。 在這種情況下,切換標志show
。
@State private var index = 0
@State private var show = true
private let images = (1...8).map { Image("background\($0)") }
private let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
ZStack {
if self.show {
images[self.index]
.transition(AnyTransition.opacity.animation(.easeInOut(duration: 1.0)))
}
}.onReceive(timer) { _ in
print(self.index)
self.index += 1
self.show.toggle()
if self.index > 4 { self.index = 0 }
}
}
瞧!
另外,據我所知, Color
不是View
。
Color 是后期綁定令牌:SwiftUI 僅在給定環境中使用它之前將其解析為具體值。
參考: https : //developer.apple.com/documentation/swiftui/color
我稍微改變了你的例子,現在背景圖像隨着動畫而改變。 但我不能建議,為什么同樣的事情對Color
或Image
不起作用。 所以,這是我的工作示例,也許它會將您推向正確的方向:
struct AnimatedBackground: View {
@State private var index = 0
private let images: [Image] = ["trash", "star", "circle", "circle.fill", "square", "cloud"].map{ Image(systemName: $0) }
private let timer = Timer.publish(every: 3, on: .main, in: .common).autoconnect()
var body: some View {
ZStack {
ForEach(images.indices, id: \.self) { imageIndex in
self.images[imageIndex]
.resizable()
.transition(.opacity)
.opacity(imageIndex == self.index ? 1 : 0)
}
}
.onReceive(timer) { _ in
withAnimation {
self.index = self.index < self.images.count - 1 ? self.index + 1 : 0
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.