【发布时间】:2020-11-15 18:10:10
【问题描述】:
在我的应用程序中,我想在卡片和全屏覆盖之间创建一个“英雄”动画,matchedGeometryEffect 似乎很适合。但是,无论我尝试什么,我都无法让动画按预期工作,而且它看起来一点也不像通常的 matchedGeometryEffect 动画。 Here's 到目前为止的样子。这是我目前拥有的:(为大量代码道歉,但这是必要的,因为对于一个简单的视图来说,它工作正常)
Something.swift
struct Something: Identifiable {
let id = UUID()
let image: Image
}
ContentView.swift
struct ContentView: View {
@Namespace var namespace
let items: [Something] = [
Image("a"), Image("b")
].map { Something(image: $0 )}
@State var selectedItem: Something?
var body: some View {
ZStack {
VStack {
ScrollView {
VStack(alignment: .leading) {
ForEach(items) { item in
CardView(
image: item.image,
namespace: namespace,
isSource: self.selectedItem == nil,
id: item.id
)
.background(Color.white)
.contentShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
.zIndex(1)
.onTapGesture {
withAnimation(.spring()) {
self.selectedItem = item
}
}
}
}
}
}
.overlay(EmptyView())
if let item = selectedItem {
EventView(
image: item.image
) {
self.selectedItem = nil
}
.matchedGeometryEffect(id: item.id, in: namespace, isSource: false)
.zIndex(2)
}
}
.animation(.spring())
.transition(.scale)
}
}
CardView.swift
struct CardView: View {
let image: Image
let namespace: Namespace.ID
let isSource: Bool
let id: UUID
var body: some View {
VStack(alignment: .leading) {
ZStack(alignment: .bottomTrailing) {
image
.resizable()
.aspectRatio(contentMode: .fill)
.frame(height: 225)
.clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
.matchedGeometryEffect(id: id, in: namespace, isSource: isSource)
}
}
}
}
EventView.swift
struct EventView: View {
let image: Image
let onDismiss: () -> Void
var body: some View {
image
.resizable()
.aspectRatio(contentMode: .fill)
.edgesIgnoringSafeArea(.all)
.onTapGesture(perform: onDismiss)
}
}
任何关于添加或更改以使其正常工作的建议将非常感谢,谢谢!!
【问题讨论】:
-
由于缺少依赖关系,代码不可测试...您能详细说明一下吗? How to create a Minimal, Reproducible Example...顺便说一句,
matchedGeometryEffect至少需要 pair 来匹配。我没有看到对应的对象。 -
@Asperi 道歉,请参阅我编辑的帖子
标签: ios animation swiftui transition