MGE ⟩ animation

SwiftUIDrawingMatched Geometry Effect

⬆️ 需要: .frame()

import SwiftUI
import PlaygroundSupport
import Extensions            // 🌀 View+
PlaygroundPage.current.setLiveView(ContentView())

struct ContentView: View {
    
    // ⭐️ for matched geometry effect (i.e. Magic Move)
    @Namespace private var ns
    
    @State private var flag: Bool = true
    
    var body: some View {
        VStack(spacing: 0) {
            HStack {
                viewA1    // ⭐️ source/target of matched geometry effect
                Spacer()
                squares
            }
            controls
        }
        .frame(width: 400)
        .border(.secondary)
    }
}

extension ContentView {
    
    /// controls
    var controls: some View {
        HStack(spacing: 0) {
            Group {
                // ⭐️ animation
                Toggle("Anime", isOn: $flag.animation(.easeInOut(duration: 4)))
                Toggle("No", isOn: $flag).tint(.pink)
            }
            .padding()
            .border(.secondary)
        }
    }
    
    /// ⭐️ viewA1
    @ViewBuilder var viewA1: some View {
        if flag {
            Color.green
                // ----------------------------------
                // ⭐️ source/target
                .matchedGeometryEffect(id: 1, in: ns)
                // ----------------------------------
                .frame(100)        // 🌀 View+
        }
    }
    
    /// ⭐️ viewA2
    @ViewBuilder var viewA2: some View {
        if !flag {
            Circle()
                .fill(Color.blue)
                // ----------------------------------
                // ⭐️ target/source
                .matchedGeometryEffect(id: 1, in: ns)
                // ----------------------------------
                .padding(2)
                .frame(50)        // 🌀 View+
                .border(.secondary)
        }
    }
    
    /// square
    var square: some View {
        Color.pink
            .frame(50)            // 🌀 View+
            .border(.secondary)
    }
    
    /// square stack
    var squares: some View {
        VStack(spacing: 0) {
            square
            viewA2        // ⭐️ target/source of matched geometry effect
            square
        }
    }
}

Last updated