โœจMGE โŸฉ animation

SwiftUI โŸฉ Drawing โŸฉ Matched Geometry Effect โŸฉ

โฌ†๏ธ ้œ€่ฆ๏ผš view + .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