我正在实现自定义菜单视图,从顶部尾随位置过渡外观。我正在使用matchedGeometryEffect
视图背景。问题在于第二视图的子视图。它们出现在动画结束之前。你可以在下面看到:
如何将这些按钮视图与父视图的动画同步?
在我的代码下面:
struct ContentView: View {
@State var show = false
@Namespace var namespace
var body: some View {
VStack(spacing: 0) {
HStack(spacing: 0) {
Spacer()
Button(action: {
withAnimation(.linear(duration: 1.2)) { // Longer duration for demo of issue
show.toggle()
}
}) {
Image(systemName: "ellipsis.circle")
.font(.title3)
.background( !show ?
Color.clear
.matchedGeometryEffect(id: "topMenuToggle", in: namespace, properties: .position)
: nil
)
}
}
.padding()
Color.clear
.overlay(
show ? MenuView(namespace: namespace) : nil
, alignment: .topTrailing
)
}
.foregroundColor(.white)
.background(Color.black.ignoresSafeArea())
}
}
struct MenuView: View {
let namespace: Namespace.ID
var body: some View {
VStack(spacing: 0) {
Button(action: {
}) {
HStack(spacing: 0) {
Text("Save video")
.font(.body)
Spacer(minLength: 0)
Image(systemName: "arrow.down.circle")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 20)
}
}
.padding(.top, 18)
.padding(.bottom, 18)
.padding(.horizontal, 14)
Rectangle()
.fill(Color.white.opacity(0.1))
.frame(maxWidth: .infinity, maxHeight: 1)
Button(action: {
}) {
HStack(spacing: 0) {
Text("Report")
.font(.body)
Spacer(minLength: 0)
Image(systemName: "exclamationmark.bubble")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 20)
}
}
.padding(.top, 16)
.padding(.bottom, 18)
.padding(.horizontal, 14)
}
.foregroundColor(.white)
.frame(width: 250)
.background(
Color.white.opacity(0.2)
.matchedGeometryEffect(id: "topMenuToggle", in: namespace, anchor: .bottomLeading)
)
.cornerRadius(12)
}
}