Skip to content

Instantly share code, notes, and snippets.

@thexande
Created July 11, 2020 00:23
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save thexande/610ecaca4d381e33295e746256f50884 to your computer and use it in GitHub Desktop.
Save thexande/610ecaca4d381e33295e746256f50884 to your computer and use it in GitHub Desktop.
A playground showing how the .matchedGeometryEffect modifier works.
import SwiftUI
import PlaygroundSupport
final class Item: Identifiable {
let color: Color
let id = UUID()
var displayDetail: Bool
init(color: Color, displayDetail: Bool = false) {
self.color = color
self.displayDetail = displayDetail
}
}
struct ItemView: View {
let item: Item
var body: some View {
RoundedRectangle(cornerRadius: 18)
.foregroundColor(item.color)
.shadow(radius: 10)
}
}
struct DemoView: View {
@Namespace private var animation
@State var showDetail = false
let items: [Item] = [.orange, .green, .purple, .pink, .black, .blue].map {
.init(color: $0)
}
let columns: [GridItem] = .init(repeating: .init(.fixed(200), spacing: 18),
count: 2)
var body: some View {
VStack { if showDetail { detail } else { main } }
}
var main: some View {
LazyVGrid(columns: columns, spacing: 18) {
ForEach(items) { item in
ItemView(item: item)
.frame(minWidth: 200, minHeight: 200)
.matchedGeometryEffect(id: item.id, in: animation)
.animation(.spring(response: 0.5, dampingFraction: 0.9))
.onTapGesture {
withAnimation {
item.displayDetail = true
showDetail = true
}
}
}
}.padding(.all, 18)
}
var detail: some View {
ForEach(items) { item in
if item.displayDetail {
ItemView(item: item)
.frame(maxWidth: 260, maxHeight: 260)
.matchedGeometryEffect(id: item.id, in: animation)
.animation(.spring(response: 0.5, dampingFraction: 0.9))
.onTapGesture {
withAnimation {
item.displayDetail = false
showDetail = false
}
}
}
}
}
}
PlaygroundPage.current.liveView = UIHostingController(rootView: DemoView())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment