SwiftUI:匹配的几何效果不起作用
SwiftUI: Matched Geometry Effect doesn't work
我正在制作使用匹配几何效果的应用程序。它匹配嵌入在两个不同视图中的两个矩形。它没有按预期工作。请帮我。
这是测试视图:
struct ContentViewTest: View {
@State var details = false
@Namespace var animation
var body: some View {
ZStack {
if !details {
TestView2(details: $details, anim: animation)
}
if details {
TestView1(details: $details, anim: animation)
}
}
}
}
这是 TestView1:
struct TestView1: View {
@Binding var details: Bool
var anim: Namespace.ID
var body: some View {
ZStack{
Color.gray.ignoresSafeArea()
Color.red.frame(width: 300, height: 700)
.matchedGeometryEffect(id: "id1", in: anim)
.onTapGesture {
withAnimation {
details = false
}
}
}
}
}
这是 TestView2:
struct TestView2: View {
@Binding var details: Bool
var anim: Namespace.ID
var body: some View {
ZStack{
Color.green.ignoresSafeArea()
Color.red.frame(width: 200, height: 200)
.matchedGeometryEffect(id: "id1", in: anim)
.onTapGesture {
withAnimation {
details = true
}
}
}
}
}
这是解决您的问题的方法,在正确的位置使用 transition 和 matchedGeometryEffect:
struct ContentView: View {
@State var details = false
@Namespace var namespace
private let id: String = "myID"
var body: some View {
if (details) {
TestView1(details: $details, id: id, namespace: namespace)
}
else {
TestView2(details: $details, id: id, namespace: namespace)
}
}
}
struct TestView1: View {
@Binding var details: Bool
let id: String
var namespace: Namespace.ID
var body: some View {
ZStack {
Color.gray.ignoresSafeArea()
Color.red
.matchedGeometryEffect(id: id, in: namespace)
.transition(.scale(scale: 1.0))
.frame(width: 300, height: 700)
.onTapGesture {
withAnimation {
details = false
}
}
}
}
}
struct TestView2: View {
@Binding var details: Bool
let id: String
var namespace: Namespace.ID
var body: some View {
ZStack {
Color.green.ignoresSafeArea()
Color.red
.matchedGeometryEffect(id: id, in: namespace)
.transition(.scale(scale: 1.0))
.frame(width: 200, height: 200)
.onTapGesture {
withAnimation {
details = true
}
}
}
}
}
只需添加 properties
位置(在两个匹配的视图中),如下所示
Color.red.frame(width: 300, height: 700)
.matchedGeometryEffect(id: "id1", in: anim, properties: .position) // << here !!
或(取决于您想要达到的效果)更改修饰符的顺序(对于两个视图),例如
Color.red
.matchedGeometryEffect(id: "id1", in: anim) // << here !!
.frame(width: 300, height: 700)
测试 Xcode 13.2 / iOS 15.2
我正在制作使用匹配几何效果的应用程序。它匹配嵌入在两个不同视图中的两个矩形。它没有按预期工作。请帮我。 这是测试视图:
struct ContentViewTest: View {
@State var details = false
@Namespace var animation
var body: some View {
ZStack {
if !details {
TestView2(details: $details, anim: animation)
}
if details {
TestView1(details: $details, anim: animation)
}
}
}
}
这是 TestView1:
struct TestView1: View {
@Binding var details: Bool
var anim: Namespace.ID
var body: some View {
ZStack{
Color.gray.ignoresSafeArea()
Color.red.frame(width: 300, height: 700)
.matchedGeometryEffect(id: "id1", in: anim)
.onTapGesture {
withAnimation {
details = false
}
}
}
}
}
这是 TestView2:
struct TestView2: View {
@Binding var details: Bool
var anim: Namespace.ID
var body: some View {
ZStack{
Color.green.ignoresSafeArea()
Color.red.frame(width: 200, height: 200)
.matchedGeometryEffect(id: "id1", in: anim)
.onTapGesture {
withAnimation {
details = true
}
}
}
}
}
这是解决您的问题的方法,在正确的位置使用 transition 和 matchedGeometryEffect:
struct ContentView: View {
@State var details = false
@Namespace var namespace
private let id: String = "myID"
var body: some View {
if (details) {
TestView1(details: $details, id: id, namespace: namespace)
}
else {
TestView2(details: $details, id: id, namespace: namespace)
}
}
}
struct TestView1: View {
@Binding var details: Bool
let id: String
var namespace: Namespace.ID
var body: some View {
ZStack {
Color.gray.ignoresSafeArea()
Color.red
.matchedGeometryEffect(id: id, in: namespace)
.transition(.scale(scale: 1.0))
.frame(width: 300, height: 700)
.onTapGesture {
withAnimation {
details = false
}
}
}
}
}
struct TestView2: View {
@Binding var details: Bool
let id: String
var namespace: Namespace.ID
var body: some View {
ZStack {
Color.green.ignoresSafeArea()
Color.red
.matchedGeometryEffect(id: id, in: namespace)
.transition(.scale(scale: 1.0))
.frame(width: 200, height: 200)
.onTapGesture {
withAnimation {
details = true
}
}
}
}
}
只需添加 properties
位置(在两个匹配的视图中),如下所示
Color.red.frame(width: 300, height: 700)
.matchedGeometryEffect(id: "id1", in: anim, properties: .position) // << here !!
或(取决于您想要达到的效果)更改修饰符的顺序(对于两个视图),例如
Color.red
.matchedGeometryEffect(id: "id1", in: anim) // << here !!
.frame(width: 300, height: 700)
测试 Xcode 13.2 / iOS 15.2