ios 在SwiftUI非对称过渡动画中切换方向时,移除边不正确

eqqqjvef  于 2023-02-26  发布在  iOS
关注(0)|答案(1)|浏览(143)

我尝试在SwiftUI中制作一系列图像的“幻灯片"效果。我在Stack Overflow上找到了this答案,并尝试实现它。起初,它似乎工作。但是,当你切换方向时,需要删除的图像从错误的方向删除。似乎删除边缘只是没有识别出最初的方向变化。
下面是一个示例视频:https://streamable.com/fmbcij

import SwiftUI

struct Slideshow: View {
    
    @State private var image: Image?
    @State private var index: Int = 1
    @State private var forwards = false

    var body: some View {
        VStack {
            image?
                .resizable()
                .scaledToFit()
                .transition(
                    .asymmetric(
                        insertion: .move(edge: forwards ? .trailing : .leading),
                        removal: .move(edge: forwards ? .leading : .trailing)
                    )
                )
                .animation(.default)
                .id(UUID())

            Text(index.formatted())
            Text(String(forwards)).padding(.bottom)

            Button("Next", action: {
                index += 1
                forwards = true
                loadImage()
            })

            Button("Previous", action: {
                index -= 1
                forwards = false
                loadImage()
            })
        }
        .onAppear(perform: loadImage)
    }

    func loadImage() {
        let strname = String("Test\(index)")
        image = Image(strname)
    }
}

struct Slideshow_Previews: PreviewProvider {
    static var previews: some View {
        Slideshow()
    }
}

我试过编辑这段代码来跟踪任何方向开关,并确保插入/移除字段是正确的。我也试过延迟动画,以确保移除边缘是正确的。我还试过使用条件if扩展,见下面的代码。这两种方法都不成功。

.if(forwards) {
    $0.transition(
        .asymmetric(
            insertion: .move(edge: .trailing),
            removal: .move(edge: .leading)
        )
    )
}
.if(!forwards) {
    $0.transition(
        .asymmetric(
            insertion: .move(edge: .leading),
            removal: .move(edge: .trailing)
        )
    )
}

这是一个SwiftUI错误,还是可以做些什么来解决这个问题?

9avjhtql

9avjhtql1#

我发现在插入视图后不能修改过渡。
我找到的唯一解决方案是更改转换,然后更改视图的ID。然而,这将触发视图插入,这将触发当前定义的插入转换。因此,您需要使用.identity的插入转换,以防止在更改ID和插入新视图时出现动画。
因此,您需要三个转换:一个具有您想要的插入过渡,移除.identity,第二个具有.identity和.move(edge:.leading)和第三个.move(edge:.拖尾)。

相关问题