是否可以使用同一图像通过淡入淡出动画更改图像?(斯威夫特用户界面)

Mik*_*ikk 8 animation image fading swiftui

根据我的逻辑,对图像进行点击手势时,应该使用淡入淡出动画来更改,但实际结果是图像在没有动画的情况下发生变化。如果重要,请使用 Xcode 11.3.1、模拟器 13.2.2/13.3 进行测试。

PS图像被命名为“img1”、“img2”、“img3”等。

enum ImageEnum: String {
    case img1
    case img2
    case img3

    func next() -> ImageEnum {
        switch self {
            case .img1: return .img2
            case .img2: return .img3
            case .img3: return .img1
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
struct ContentView: View {
    @State private var img = ImageEnum.img1
    var body: some View {
        Image(img.rawValue)
            .onTapGesture {
                withAnimation {
                    self.img = self.img.next()
                }
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

ser*_*nic 11

我还没有测试过这段代码,但是这样的代码可能会更简单一些:

struct ContentView: View {
    @State private var img = ImageEnum.img1
    var body: some View {
        Image(img.rawValue)
            .id(img.rawValue)
            .transition(.opacity.animation(.default))
            .onTapGesture {
                withAnimation {
                    self.img = self.img.next()
                }
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

Image这个想法是通过将视图的标识绑定到文件名本身来告诉 SwiftUI 在资产的文件名发生更改时重新绘制。当文件名更改时,SwiftUI 假定视图已更改,并且必须将新视图添加到视图层次结构中,从而触发转换。


Asp*_*eri 8

更新:使用 Xcode 13.3 / iOS 15.4 重新测试

这是使用一个图像的可能方法(为了演示,对使用默认图像进行了一些小的修改)。重要的更改已用注释标记。

演示

enum ImageEnum: String {
    case img1 = "1.circle"
    case img2 = "2.circle"
    case img3 = "3.circle"

    func next() -> ImageEnum {
        switch self {
            case .img1: return .img2
            case .img2: return .img3
            case .img3: return .img1
        }
    }
}
struct QuickTest: View {
    @State private var img = ImageEnum.img1
    @State private var fadeOut = false
    var body: some View {
        Image(systemName: img.rawValue).resizable().frame(width: 300, height: 300)
            .opacity(fadeOut ? 0 : 1)
            .animation(.easeInOut(duration: 0.25), value: fadeOut)    // animatable fade in/out
            .onTapGesture {
                self.fadeOut.toggle()                 // 1) fade out

                // delayed appear
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
                    withAnimation {
                        self.img = self.img.next()    // 2) change image
                        self.fadeOut.toggle()         // 3) fade in
                    }
                }
            }
    }
}
Run Code Online (Sandbox Code Playgroud)