在 ScrollView 中动画位置变化

问题描述 投票:0回答:1
  • 我对伪代码感到抱歉,但我不允许分享我的代码。

我有一个 ScrollView,其中包含顶部的固定项目和底部的未固定项目。

 ______________
|    Item 1    |
|    Item 2    |
|    Item 3    |
|--------------|
|    Item 4    |
|    Item 5    |
|    Item 6    |
|    Item 7    |
|    Item 8    |
|______________|

Scroll 视图由两个集合(pinnedItems 和 unpinnedItems)填充,使用 ScrollView 中的两个 ForEach 子句。

var pinnedItems = ["Item 1", "Item 2", "Item 3"]
var unpinnedItems = ["Item 4", "Item 5", "Item 6", "Item 7", "Item 8"]
ScrollView {
    ForEach(pinnedTasks) { task in
        NavigationLink(value: NavigationPath.task(task)) {
            TaskCardView(task: task, onPinning: {
                withAnimation {
                    togglePinnedTask(task: task)
                }
            })
            .padding(.bottom)
        }.buttonStyle(.plain)
    }


    Divider()
        .frame(minHeight: 3)
        .background(.gray)
        .padding(.bottom)


    ForEach(unPinnedTasks) { task in
        NavigationLink(value: NavigationPath.task(task)) {
            TaskCardView(task: task, onPinning: {
                withAnimation {
                    togglePinnedTask(task: task)
                }
            })
            .padding(.bottom)
        }.buttonStyle(.plain)
    }
}
                

togglePinnedTask() 函数从一个集合中删除任务并将其插入到另一个集合中。

自动动画只会淡化任务卡。我想让他们“飞”到新的岗位。这样做的方法是什么?

animation swiftui scrollview
1个回答
0
投票

您可以使用

matchedGeometryEffect
。这是一个简单的例子:

struct ContentView: View {
    @State private var pinnedItems = ["Item 1", "Item 2", "Item 3"]
    @State private var unpinnedItems = ["Item 4", "Item 5", "Item 6", "Item 7", "Item 8"]
    @Namespace var ns
    
    var body: some View {
        VStack {
            ScrollView {
                VStack {
                    ForEach(pinnedItems, id: \.self) { item in
                        Text(item)
                            .matchedGeometryEffect(id: item, in: ns)
                    }
                    ForEach(unpinnedItems, id: \.self) { item in
                        Text(item)
                            .matchedGeometryEffect(id: item, in: ns)
                    }
                }
            }

            // as an example to trigger the animation
            Button("Change Pins") {
                withAnimation {
                    pinnedItems.append(unpinnedItems.removeLast())
                }
            }
        }
    }
}

请注意,在

matchedGeometryEffect
ForEach
中,我都使用
item
本身作为 id。在您的真实代码中,您的项目可能符合
Identifiable
并且您应该使用它们的
id
属性。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.