79737929

Date: 2025-08-17 15:58:00
Score: 1
Natty:
Report link

@mickben and @Confused Vorlon both have good solutions. Here is an adaptaion for Swift 6 / iOS 26:

import SwiftUI

@Observable
final class SharedNamespace {
    var id: Namespace.ID!
    init(_ namespace: Namespace.ID? = nil) {
        if let namespace = namespace {
            self.id = namespace
        }
    }
}

struct SharedNamespaceEnvironmentKey: @MainActor EnvironmentKey {
    @MainActor static let defaultValue: SharedNamespace = SharedNamespace()
}

extension EnvironmentValues {
    @MainActor
    var namespace: SharedNamespace {
        get { self[SharedNamespaceEnvironmentKey.self] }
        set { self[SharedNamespaceEnvironmentKey.self] = newValue }
    }
}

extension View {
    func namespace(_ value: Namespace.ID) -> some View {
        environment(\.namespace, SharedNamespace(value))
    }
}

Usage:

struct HomeView: View {
    @Namespace var namespace
    @State var isDisplay = true

    var body: some View {
        ZStack {
            if isDisplay {
                View1(namespace: namespace, isDisplay: $isDisplay)
            } else {
                View2(namespace: namespace, isDisplay: $isDisplay)
            }
        }
        .namespace(namespace)
    }
}

struct View1: View {
    @Environment(\.namespace) private var namespace

    @Binding var isDisplay: Bool
    var body: some View {
        VStack {
            Image("plant")
                .resizable()
                .frame(width: 150, height: 100)
                .matchedGeometryEffect(id: "img", in: namespace.id)
            Spacer()
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.blue)
        .onTapGesture {
            withAnimation {
                self.isDisplay.toggle()
            }
        }
    }
}
     
Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @and
  • User mentioned (0): @both
  • Looks like a comment (1):
  • Low reputation (0.5):
Posted by: biodynamiccoffee