Hi,
I had to improvise some things but it should work like intended,
struct ContentView: View {
@State private var selectedOption: DropdownMenuOption? = DropdownMenuOption.option1
var body: some View {
VStack {
Text("Hello World!")
DropdownMenu(selectedOption: $selectedOption, placeholder: "Placeholder", options: [DropdownMenuOption.option1, DropdownMenuOption.option2])
.zIndex(1)
Text("Hello Again")
}
}
}
struct DropdownMenu: View {
// Used to show or hide drop-down menu options
@State private var isOptionsPresented: Bool = false
// Used to bind user selection
@Binding var selectedOption: DropdownMenuOption?
let placeholder: String
let options: [DropdownMenuOption]
var body: some View {
Button(action: {
self.isOptionsPresented.toggle()
}) {
HStack {
Text(selectedOption == nil ? placeholder : selectedOption!.rawValue)
.fontWeight(.medium)
.foregroundColor(selectedOption == nil ? .gray : .black)
Spacer()
Image(systemName: self.isOptionsPresented ? "chevron.up" : "chevron.down")
.fontWeight(.medium)
.foregroundColor(.black)
}
.padding(.horizontal)
.frame(height: 60)
.overlay {
RoundedRectangle(cornerRadius: 4)
.stroke(.gray, lineWidth: 2)
}
.padding(.horizontal)
}
.overlay(alignment: .top) {
VStack {
if self.isOptionsPresented {
Spacer(minLength: 64)
DropdownMenuList(options: self.options, onSelectedAction: { option in
self.isOptionsPresented = false
self.selectedOption = option
})
}
}
.padding(.horizontal)
.padding( .bottom, self.isOptionsPresented ? CGFloat(self.options.count * 32 ) > 160
? 192
: CGFloat(self.options.count * 32) + 32
: 0
)
}
}
}
struct DropdownMenuList: View {
// the dropdown menu list options
let options: [DropdownMenuOption]
// an action called when user select an option
let onSelectedAction: (_ option: DropdownMenuOption) -> Void
var body: some View {
ScrollView {
LazyVStack(alignment: .leading, spacing: 02) {
ForEach(options, id: \.self) { option in
Text(option.rawValue)
.foregroundColor(.primary)
}
.padding(.horizontal)
}
}
.frame(height: 60)
.background(.white)
.overlay {
RoundedRectangle(cornerRadius: 04)
.stroke(.gray, lineWidth: 02)
}
}
}