@Namespace는 iOS 14에서 새로 생긴 propery wrapper 이다. iOS 13에서 사용하기 위해서는 코드를 사용해야 한다.
아래와 같이 코드를 작성하고,
더보기
import SwiftUI
@available(iOS 14, *)
struct NamespaceWrapper<Content: View>: View {
@Namespace var namespace
var content: Content
var body: some View {
content.environment(\.namespace, namespace)
}
}
@available(iOS 14, *)
struct NamespaceReader<Content: View, ID: Hashable>: View {
@Environment(\.namespace) var namespace
var content: Content
var id: ID
var anchor: UnitPoint = .center
var isSource: Bool = true
var body: some View {
content.matchedGeometryEffect(id: id, in: namespace!, anchor: anchor, isSource: isSource)
}
}
@available(iOS 14, *)
struct NamespaceKey: EnvironmentKey {
static let defaultValue: Namespace.ID? = nil
}
@available(iOS 14, *)
extension EnvironmentValues {
var namespace: Namespace.ID? {
get {
self[NamespaceKey.self]
}
set {
self[NamespaceKey.self] = newValue
}
}
}
extension View {
func namespaced() -> AnyView {
if #available(iOS 14, *) {
return AnyView(NamespaceWrapper(content: self))
} else {
return AnyView(self)
}
}
func namespacedMatchedGeometryEffect<ID>(id: ID, anchor: UnitPoint = .center, isSource: Bool = true) -> some View where ID : Hashable {
if #available(iOS 14, *) {
return AnyView(NamespaceReader(content: self, id: id, anchor: anchor, isSource: isSource))
} else {
return AnyView(self)
}
}
}
아래와 같이 사용한다.
더보기
struct ContentView: View {
@State private var isExpanded = false
var body: some View {
Group {
if isExpanded {
VStack {
RoundedRectangle(cornerRadius: 10)
.foregroundColor(Color.pink)
.frame(width: 60, height: 60)
.namespacedMatchedGeometryEffect(id: "rect")
Text("Hello SwiftUI!").fontWeight(.semibold)
.namespacedMatchedGeometryEffect(id: "text")
}
} else {
HStack {
Text("Hello SwiftUI!").fontWeight(.semibold)
.namespacedMatchedGeometryEffect(id: "text")
RoundedRectangle(cornerRadius: 10)
.foregroundColor(Color.pink)
.frame(width: 60, height: 60)
.namespacedMatchedGeometryEffect(id: "rect")
}
}
}.onTapGesture {
withAnimation {
isExpanded.toggle()
}
}.namespaced()
}
}
출처
https://gist.github.com/Snowy1803/c077b60190c2543a823526a0c73ff142
댓글