SwiftUI 中的淡入淡出图像似乎不起作用

Chr*_*ris 5 ios swift swiftui xcode11

我想实现一个动画背景,在 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 }
      }
  }
Run Code Online (Sandbox Code Playgroud)

但是,如果我用 [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 }
      }
  }
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么会这样吗?目前这只是 SwiftUI 中的一个错误吗?

我在以前的应用程序中使用各种 addSubview 调用实现了类似的效果,这些调用为覆盖视图的不透明度设置动画——在这个勇敢的新 SwiftUI 世界中,我们不需要摆弄各种东西,对吧?

Але*_*кий 6

我稍微改变了你的例子,现在背景图像随着动画而改变。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
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)