Untitled
unknown
plain_text
a year ago
7.6 kB
7
Indexable
import SwiftUI
struct DropdownView: View {
@StateObject var dropdownState = DropdownState()
let firstOptions: [String]
let secondOptions: [String]
let firstPlaceholder: String
let secondPlaceholder: String
let selectedOrder: String
var body: some View {
ZStack {
Color.clear
.contentShape(Rectangle())
.onTapGesture {
dropdownState.isFirstDropdownVisible = false
dropdownState.isSecondDropdownVisible = false
}
HStack(spacing: 12) {
VStack {
GeometryReader { geometry in
Button(action: {
dropdownState.isFirstDropdownVisible.toggle()
dropdownState.isSecondDropdownVisible = false // Close the second dropdown
}) {
HStack {
Text(dropdownState.selectedFirstOption.isEmpty ? firstPlaceholder : dropdownState.selectedFirstOption)
.font(.plusJakartaSans(size: 15, weight: .semibold)).foregroundColor(Color(hex: "#0F172A"))
Spacer()
Image(systemName: dropdownState.isFirstDropdownVisible ? "chevron.up" : "chevron.down") .foregroundColor(Color(hex: "#A4ACB9"))
.animation(.easeInOut(duration: 0.1), value: dropdownState.isFirstDropdownVisible)
}
.padding()
.frame(maxWidth: .infinity)
.frame(height: 36)
.background(Color.green.opacity(0.2))
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.green, lineWidth: 1)
)
}
dropdownState.isFirstDropdownVisible
? DropdownListView(
options: firstOptions,
selectedOption: $dropdownState.selectedFirstOption, selectedOrder: selectedOrder,
isDropdownVisible: $dropdownState.isFirstDropdownVisible,
buttonFrame: geometry.frame(in: .local)
).environmentObject(dropdownState)
: nil
}
.frame(height: 36)
}
// Second Dropdown
VStack {
GeometryReader { geometry in
Button(action: {
dropdownState.isSecondDropdownVisible.toggle()
dropdownState.isFirstDropdownVisible = false // Close the first dropdown
}) {
HStack {
Text(dropdownState.selectedSecondOption.isEmpty ? secondPlaceholder : dropdownState.selectedSecondOption) .font(.plusJakartaSans(size: 15, weight: .semibold)).foregroundColor(Color(hex: "#0F172A"))
Spacer()
Image(systemName: dropdownState.isSecondDropdownVisible ? "chevron.up" : "chevron.down") .foregroundColor(Color(hex: "#A4ACB9"))
.animation(.easeInOut(duration: 0.1), value: dropdownState.isSecondDropdownVisible)
}
.padding()
.frame(maxWidth: .infinity)
.frame(height: 36)
.background(Color.green.opacity(0.2))
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.green, lineWidth: 1)
)
}
dropdownState.isSecondDropdownVisible
? DropdownListView(
options: secondOptions,
selectedOption: $dropdownState.selectedSecondOption, selectedOrder: selectedOrder,
isDropdownVisible: $dropdownState.isSecondDropdownVisible,
buttonFrame: geometry.frame(in: .local)
) .environmentObject(dropdownState)
: nil
}
.frame(height: 36)
}
}
.animation(.easeInOut, value: dropdownState.isFirstDropdownVisible || dropdownState.isSecondDropdownVisible)
}
}
}
// Dropdown List as Overlay
struct DropdownListView: View {
let options: [String]
@Binding var selectedOption: String
var selectedOrder: String
@Binding var isDropdownVisible: Bool
let buttonFrame: CGRect
@StateObject var dropdownState = DropdownState() // Instantiate the shared state
var body: some View {
VStack(spacing: 0) {
ForEach(options, id: \.self) { option in
Button(action: {
if dropdownState.isSecondDropdownVisible{
dropdownState.selectedSecondOption = option
selectedOption = option
isDropdownVisible = false
}else{
dropdownState.selectedFirstOption = option
selectedOption = option
isDropdownVisible = false
}
}) {
HStack(spacing: 12) {
Image(selectedOption == option ? "Radio_1" : "Radio_Button") .foregroundColor(Color.black)
// Spacer()
Text(option)
.foregroundColor(Color.black)
Spacer()
}
.padding()
.frame(maxWidth: .infinity)
}
.background(Color.white)
.overlay(
Rectangle()
.frame(height: 1)
.foregroundColor(Color.gray.opacity(0.2)),
alignment: .bottom
)
//
}
}
.background(Color.white)
.cornerRadius(8)
.shadow(radius: 4)
.position(x: buttonFrame.midX, y: buttonFrame.midY + 150) // Position below button
.zIndex(1) // Ensure it appears above other elements
}
}
// ObservableObject to store the dropdown state
class DropdownState: ObservableObject {
@Published var selectedFirstOption: String = ""
@Published var selectedSecondOption: String = ""
@Published var isFirstDropdownVisible: Bool = false
@Published var isSecondDropdownVisible: Bool = false
}
// Preview
struct DropdownView_Previews: PreviewProvider {
static var previews: some View {
DropdownView(firstOptions: ["Option 1", "Option 2", "Option 3"], secondOptions: ["Filter 1", "Filter 2", "Filter 3"], firstPlaceholder: "Select Sort", secondPlaceholder: "Select Filter", selectedOrder: "")
.environmentObject(DropdownState())
}
}
Editor is loading...
Leave a Comment