Skip to content

Instantly share code, notes, and snippets.

@Shriram-Vasudevan
Created February 23, 2025 14:03
Show Gist options
  • Save Shriram-Vasudevan/3f0e34c0cdb6bd3e4435a5492f5da37e to your computer and use it in GitHub Desktop.
Save Shriram-Vasudevan/3f0e34c0cdb6bd3e4435a5492f5da37e to your computer and use it in GitHub Desktop.
struct CurvedSheed: View {
@Binding var isOpen: Bool
@State private var sheetOffset: CGFloat = 1000
@State private var backgroundOpacity: Double = 0
var body: some View {
ZStack {
// Background overlay
Color.black
.opacity(backgroundOpacity)
.ignoresSafeArea()
.onTapGesture { dismiss() }
// Sheet content
VStack(spacing: 0) {
Spacer()
// Curved top shape
CurveShape()
.fill(Color(.systemGray6))
.frame(height: 24)
// Content
VStack(spacing: 16) {
// Handle indicator
RoundedRectangle(cornerRadius: 2.5)
.fill(Color(.systemGray3))
.frame(width: 36, height: 5)
.padding(.top, 8)
// Top row - 2 cards
HStack(spacing: 12) {
Spacer()
MinimalCard(
icon: "",
title: ""
) {
//Action
}
MinimalCard(
icon: "",
title: ""
) {
//Action
}
Spacer()
}
.padding(.horizontal, 24)
HStack(spacing: 12) {
MinimalCard(
icon: "",
title: ""
) {
//Action
}
MinimalCard(
icon: "",
title: ""
) {
//Action
}
MinimalCard(
icon: "",
title: ""
) {
//Action
}
}
.padding(.horizontal, 24)
// Close button
Button(action: dismiss) {
Circle()
.fill(Color(.systemGray6))
.frame(width: 44, height: 44)
.overlay(
Image(systemName: "xmark")
.font(.system(size: 17, weight: .medium))
.foregroundColor(.primary)
)
}
.padding(.top, 8)
.padding(.bottom, 16)
}
.background(Color(.systemGray6))
}
.offset(y: sheetOffset)
.edgesIgnoringSafeArea(.bottom)
}
.onAppear { animateEntry() }
}
private func animateEntry() {
withAnimation(.spring(response: 0.6, dampingFraction: 0.8)) {
sheetOffset = 0
backgroundOpacity = 0.5
}
}
private func dismiss() {
withAnimation(.spring(response: 0.6, dampingFraction: 0.8)) {
sheetOffset = 1000
backgroundOpacity = 0
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
isOpen = false
}
}
}
struct CurveShape: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: 0, y: 24))
let center = rect.width / 2
path.addCurve(
to: CGPoint(x: rect.width, y: 24),
control1: CGPoint(x: center - 80, y: 0),
control2: CGPoint(x: center + 80, y: 0)
)
path.addLine(to: CGPoint(x: rect.width, y: rect.height))
path.addLine(to: CGPoint(x: 0, y: rect.height))
path.closeSubpath()
return path
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment