Skip to content

Instantly share code, notes, and snippets.

@carson-katri
Last active November 7, 2019 03:10
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save carson-katri/291d26d2aa436092aabc782689e2c90d to your computer and use it in GitHub Desktop.
Save carson-katri/291d26d2aa436092aabc782689e2c90d to your computer and use it in GitHub Desktop.
struct CardHeading: View {
@State private var touchZoom: Bool = false
var body: some View {
VStack(spacing: 0) {
Image("banner")
.resizable()
.aspectRatio(contentMode: ContentMode.fill)
.frame(minWidth: 0, maxWidth: .infinity, maxHeight: 400)
.clipped()
VStack(alignment: .leading) {
Text("HELLO WORLD")
.font(.caption)
.bold()
.opacity(0.5)
Text("This is a Test Card")
.font(.largeTitle)
.bold()
}
.padding([.top, .bottom, .leading])
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.background(Color("modal"))
}
.cornerRadius(10)
}
}
struct ContentView: View {
@State private var cardRect: CGRect? = nil
@State private var cardRects: [Int: CGRect] = [:]
@State private var fullscreen: Bool = false
@State private var modalRect: CGRect = .zero
@State private var expanded: Bool = false
@State private var finishedExpanding: Bool = false
@State private var selected: Int? = nil
var body: some View {
ScrollView {
ForEach(0...5, id: \.self) { (index: Int) in
CardHeading()
.frame(height: 500)
.cornerRadius(10)
.background(GeometryReader { geometry -> Text in
DispatchQueue.main.async {
self.cardRects[index] = geometry.frame(in: .global)
}
return Text("")
})
.opacity(self.selected == index && self.fullscreen ? 0 : 1)
.onTapGesture {
self.cardRect = self.cardRects[index]
self.fullscreen = true
self.selected = index
}
}
}
.padding([.leading, .trailing])
.overlay(Group {
if fullscreen && cardRect != nil {
ZStack(alignment: .topTrailing) {
ScrollView {
VStack(spacing: 0) {
CardHeading()
Text(
"""
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In cursus libero in risus placerat imperdiet. Ut a maximus justo. Aenean pretium tempor viverra. Cras maximus metus mi, sed congue ex tincidunt nec. Phasellus vitae sollicitudin justo. In quis turpis non augue rutrum facilisis. Proin tempor ante sed sodales egestas. Vestibulum eget nunc lorem. Phasellus lobortis nisi ut ante placerat molestie. Vestibulum lacinia sem neque, feugiat cursus ligula egestas eget. Nullam ullamcorper rutrum felis, eu pulvinar ligula fermentum sed. In at interdum risus.
Sed in justo nisl. Proin maximus tempus turpis nec viverra. Pellentesque orci enim, sagittis eu porttitor a, porta eget velit. Aenean accumsan, elit vel dignissim malesuada, felis lacus bibendum ante, a eleifend ligula mi molestie mi. Aliquam erat volutpat. Donec eleifend urna est, id consequat massa varius ut. Morbi hendrerit tortor faucibus augue consectetur, molestie tincidunt risus molestie. Duis finibus neque id magna aliquam, vel pulvinar dui porta. Suspendisse pellentesque congue felis finibus varius. Suspendisse a lectus justo. Nulla interdum velit quis sem maximus sagittis. Nulla semper justo velit, ac tincidunt tellus pellentesque in. Curabitur cursus nulla ac ante pellentesque, sit amet vulputate tellus maximus.
Aenean sed vestibulum magna. Nullam porta ipsum ac quam commodo, at ultrices augue imperdiet. Integer sed euismod nibh. Vivamus varius sit amet enim in facilisis. In accumsan leo facilisis quam congue, quis pulvinar nisl facilisis. Etiam molestie fringilla commodo. Sed at finibus orci, ut dignissim lorem. Mauris a neque leo. Sed maximus vel risus et vehicula. Morbi at diam eleifend, convallis diam sed, sagittis odio.
""")
.padding([.leading, .trailing, .bottom])
.frame(width: expanded ? nil : cardRect!.width, height: expanded ? nil : 0)
.opacity(expanded ? 1 : 0)
}
.background(GeometryReader { geometry -> Color in
DispatchQueue.main.async {
self.modalRect = geometry.frame(in: .global)
if self.finishedExpanding && self.modalRect.minY > 150 {
self.collapse()
}
}
return Color("modal")
})
//.foregroundColor(.black)
.frame(minWidth: 0, maxWidth: expanded ? .infinity : cardRect!.width, minHeight: expanded ? 0 : cardRect!.height, maxHeight: expanded ? .infinity : cardRect!.height)
.cornerRadius(expanded ? 0 : 10)
.position(expanded ? CGPoint(x: UIScreen.main.bounds.midX, y: modalRect.height / 2) : CGPoint(x: cardRect!.midX, y: cardRect!.midY))
.edgesIgnoringSafeArea(.top)
.animation(.spring(response: 0.5, dampingFraction: 0.5, blendDuration: 0.5))
.onAppear {
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: false) { _ in
self.expanded = true
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { _ in
self.finishedExpanding = true
}
}
}
}
.background(finishedExpanding ? Color("modal") : Color.clear)
.edgesIgnoringSafeArea(.all)
Button(action: self.collapse) {
Image(systemName: "xmark")
}
.padding()
.background(expanded ? Color("modal") : nil)
.cornerRadius(50)
.padding()
.opacity(expanded ? 1 : 0)
}
}
})
}
func collapse() {
self.expanded = false
self.finishedExpanding = false
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in
self.fullscreen = false
self.modalRect = .zero
self.selected = nil
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment