AcaMate_iOS/AcaMate/1. View/10. Common/DropDownView.swift

96 lines
2.6 KiB
Swift

//
// DropDownView.swift
// AcaMate
//
// Created by TAnine on 3/25/25.
//
import SwiftUI
class DropdownManager: ObservableObject {
static let shared = DropdownManager()
@Published var isPresented = false
@Published var items: [String] = []
@Published var anchor: CGRect = .zero
var onSelect: ((String) -> Void)?
func show(items: [String], anchor: CGRect, onSelect: @escaping (String) -> Void) {
self.items = items
self.anchor = anchor
self.onSelect = onSelect
isPresented = true
}
func dismiss() {
isPresented = false
}
}
struct DropdownButton: View {
let title: String
let items: [String]
@State private var frame: CGRect = .zero
var body: some View {
Button {
DropdownManager.shared.show(items: items, anchor: frame) { selected in
print("선택한 항목:", selected)
}
} label: {
HStack {
Text(title)
Image(systemName: "chevron.down")
}
.padding()
.background(RoundedRectangle(cornerRadius: 8).stroke(Color.gray))
}
.background(
GeometryReader { geo in
Color.clear
.onAppear {
frame = geo.frame(in: .global)
}
}
)
}
}
struct GlobalDropdownOverlay: View {
@ObservedObject var manager = DropdownManager.shared
var body: some View {
if manager.isPresented {
ZStack(alignment: .topLeading) {
Color.black.opacity(0.001)
.ignoresSafeArea()
.onTapGesture {
manager.dismiss()
}
VStack(alignment: .leading, spacing: 0) {
ForEach(manager.items, id: \.self) { item in
Button {
manager.onSelect?(item)
manager.dismiss()
} label: {
Text(item)
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
}
.buttonStyle(.plain)
.background(Color.white)
}
}
.frame(width: manager.anchor.width)
.background(RoundedRectangle(cornerRadius: 8).stroke(Color.gray))
.shadow(radius: 5)
.position(x: manager.anchor.midX, y: manager.anchor.maxY + 10)
}
}
}
}