square
下の 2 つの正方形を、共通の中心点から、それらが表示されたときの最終的な位置まで、および削除されたときに戻るようにアニメーション化しようとしています。
これが私が試したものですが、その結果、重複する位置から開始するのではなく、中央のそれぞれの近くから開始します。
struct ContentView: View {
@State var matched = true
@State var show = false
@Namespace var ns
var body: some View {
VStack {
HStack {
Spacer()
if show {
square
.matchedGeometryEffect(id: matched ? "match" : "",
in: ns, anchor: .center, isSource: false)
.animation(.easeIn)
.transition(.move(edge: .trailing ))
.onAppear { withAnimation { matched = false } }
.onDisappear { withAnimation { matched = true } }
}
Spacer()
.matchedGeometryEffect(id: "match", in: ns, anchor: .center, isSource: true)
if show {
square
.matchedGeometryEffect(id: matched ? "match" : ""
in: ns, anchor: .center, isSource: false)
.animation(.easeIn)
.transition(.move(edge: .leading))
}
Spacer()
}
Button("show") { withAnimation { show.toggle() } }
}
}
}
正方形square
は単純に次のように定義されます。
var square: some View {
Rectangle().foregroundColor(.blue)
.frame(width: 40, height: 40, alignment: .center)
}
matchedGeometryEffect
どのような作業が行われたかは、 内のオーバーレイにアタッチし、それらすべてでSpacer
明示的に指定properties: .position
することでした。
それでも、それらが表示されたときにのみ機能し、消えるときは機能しません。そこにはまだギャップがあります。
Spacer().overlay(
Color.clear
.matchedGeometryEffect(id: "match", in: ns, properties: .position, anchor: .center, isSource: true)
)
これは、この効果を達成するための正しい一般的なアプローチですか?もしそうなら、どうすればそれを機能させることができますか? それとも私はそれを過度に複雑にしましたか?