Skip to content

Instantly share code, notes, and snippets.

@enebin
Created November 13, 2023 03:56
Show Gist options
  • Save enebin/6f4179ca99c2fe4ad5bdbf54a0d2b866 to your computer and use it in GitHub Desktop.
Save enebin/6f4179ca99c2fe4ad5bdbf54a0d2b866 to your computer and use it in GitHub Desktop.
struct ContentView: View {
let circlesData = [
CircleData(
label: "Expressive",
coordinate: (x: -0.2209559268150387, y: -0.6597031040497751),
radius: 0.16753215819093129),
CircleData(
label: "Funny",
coordinate: (x: 0.3864041646343055, y: 0.6054490800846822),
radius: 0.2817543825249447),
CircleData(
label: "Extrovert",
coordinate: (x: -0.5711411358905634, y: -0.23634056797191685),
radius: 0.381890736863092),
CircleData(
label: "Positive",
coordinate: (x: -0.26152337336370673, y: 0.46187070430546906),
radius: 0.381890736863092),
CircleData(
label: "Sensitive",
coordinate: (x: 0.3709271337823364, y: -0.23634056797191685),
radius: 0.5601775328098079)
]
let widthUnit: CGFloat = 400
@State var circlePadding: CGFloat = 50
@State var isSheetDragging = false
@State var showItem: CircleData?
@Namespace var animation
var body: some View {
ZStack {
ForEach(circlesData) { datum in
circleItem(data: datum)
.onTapGesture {
showItem = datum
}
}
.zIndex(ZIndex.low.rawValue)
if let item = showItem {
BackgroundBlurringView(style: .light)
.ignoresSafeArea()
.zIndex(ZIndex.middle.rawValue)
detailView(data: item)
.onTapGesture {
self.showItem = nil
}
.zIndex(ZIndex.high.rawValue)
}
}
.animation(.spring, value: showItem)
.animation(isSheetDragging ? nil : .spring, value: circlePadding)
}
func circleItem(data: CircleData) -> some View {
Circle()
.foregroundStyle(.blue.opacity(0.4))
.overlay {
Text(data.label).font(.caption2)
}
.matchedGeometryEffect(id: data.id.uuidString, in: animation)
.frame(width: data.radius * widthUnit)
.offset(
x: data.coordinate.x * widthUnit / 2,
y: data.coordinate.y * widthUnit / 2)
}
func detailView(data: CircleData) -> some View {
VStack(alignment: .center) {
Circle()
.foregroundStyle(.blue)
.overlay {
Text(data.label).font(.title)
}
.matchedGeometryEffect(id: data.id.uuidString, in: animation)
.frame(
width: max(150, widthUnit - circlePadding),
height: max(150, widthUnit - circlePadding))
Spacer().frame(minHeight: 5, maxHeight: 30)
CustomBottomSheet(sheetHeightOffset: $circlePadding, isSheetDragging: $isSheetDragging) {
ScrollView {
ForEach(0..<10) { Text("\($0)") }
.frame(minWidth: 0, maxWidth: .infinity)
}
}
}
.transition(.move(edge: .bottom).combined(with: .opacity))
}
private enum ZIndex: CGFloat {
case high = 3
case middle = 2
case low = 0
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment