2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【初心者】Swift UIを勉強する その⑦ ーーーmatchedGeometryEffect

Last updated at Posted at 2021-03-28

はじめに

前回のアニメーションを踏まえて、matchedGeometryEffect()を使って少し複雑なアニメーションを作っていきます。
Mar-07-2021 21-53-52.gif

目次

  1. matchedGeometryEffect
  2. まとめ
  3. 参考文献

matchedGeometryEffect

matchedGeometryEffect() --- If inserting a view in the same transaction that another view with the same key is removed, the system will interpolate their frame rectangles in window space to make it appear that there is a single view moving from its old position to its new position.

・つまり、アニメーションを作成の際に、初めの状態と終わりの状態を定義すれば、プログラムが勝手に動いてくれるということです。
・例えば、以下のように楕円は初めに横100縦200として、タップされたら横200縦100に変わっていきました。しかし、変化する最中に横縦は特に指定されていません。

struct ContentView: View {
    @State var expand = false
    
    var body: some View {
        Ellipse()
            .fill(Color.blue)
            .frame(width: expand ? 100 : 200, height: expand ? 200 : 100)
            .offset(y: expand ? -250 : 0)
            .animation(.easeIn)
            .onTapGesture {
                self.expand.toggle()
            }
    }
}

      

・実際に前回作ったカードでmatchedGeometryEffect()を試していきましょう。
CourseItem()は2回呼ばれて、それぞれ初めの状態と終わりの状態を表しています。
 isSourseはビューをグループ内の他のビューのジオメトリのソースとして使用する場合にTrueを指定します。
 show.toggle()はタップされたらBoolが変わります。

CoursesView.swift
struct CoursesView: View {
    @State var show = false
    @Namespace var namespace
    
    var body: some View {
        ZStack {
            CourseItem()
                .matchedGeometryEffect(
                    id: "Card", in: namespace, isSource: !show
                )
                .frame(width: 335, height: 250)
            if show {
                CourseItem()
                    .matchedGeometryEffect(id: "Card", in: namespace)
                    .transition(.opacity)
                    .zIndex(1)
                    .edgesIgnoringSafeArea(.all)
            }
        }
        .onTapGesture {
            withAnimation(.spring()) {
                show.toggle()
            }
        }
    }
}

・この間作ったCourseRow()を使って、カードがタップされたらCourseRow()のリストを出せるようにします。
・状態が終わった後にリストを追加するので、2回目に呼ばれたCourseItem()ScrollViewに突っ込みます。
 また、全画面にしたくないので、縦を300にします。

CoursesView.swift
ScrollView {
     CourseItem()
          .matchedGeometryEffect(id: "Card", in: namespace)
          .frame(height: 300)
}

ForEachCourseRow()を表示されます。

CoursesView.swift
ForEach(0 ..< 20) { item in
      CourseRow()
}

  

まとめ

・気づいているかもしれませんが、リストの消えるタイミングが遅くて、次回はこれを解決します。

ソースコードGithub

参考文献

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?