SwiftUI Menus

From PeformIQ Upgrade
Revision as of 12:52, 17 February 2022 by PeterHarding (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Links

Examples

Menu {
    Button {
        style = 0
    } label: {
        Text("Linear")
        Image(systemName: "arrow.down.right.circle")
    }
    Button {
        style = 1
    } label: {
        Text("Radial")
        Image(systemName: "arrow.up.and.down.circle")
    }
} label: {
     Text("Style")
     Image(systemName: "tag.circle")
}


GroupBox {
    DisclosureGroup("Menu 1") {
        Text("Item 1")
        Text("Item 2")
        Text("Item 3")
    }
}

you might consider the Picker:

struct ContentView : View {
    @State private var selection = 1
    var body: some View {
        VStack {
            Picker(selection: $selection, label: Text("Choices")) {
                    Text("Five").tag(5)
                    Text("Four").tag(4)
                    Text("Three").tag(3)
                    Text("Two").tag(2)
                    Text("One").tag(1)
            }
        }
    }
}

An Alternate Approach

           Text("Options")
            .contextMenu {
                Button(action: {
                    // change country setting
                }) {
                    Text("Choose Country")
                }

                Button(action: {
                    // enable geolocation
                }) {
                    Text("Detect Location")
                }
            }

From - https://www.hackingwithswift.com/quick-start/swiftui/how-to-show-a-context-menu

Dropdowns

You need to use an overlay to display your dropdown. Otherwise, parents' layout will be wrong when you show and hide the dropdown.

demo

Here is a simple answer, and the complete answer could be found here


struct Dropdown: View {
    var options: [DropdownOption]
    var onSelect: ((_ key: String) -> Void)?

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            ForEach(self.options, id: \.self) { option in
                DropdownOptionElement(val: option.val, key: option.key, onSelect: self.onSelect)
            }
        }

        .background(Color.white)
        .cornerRadius(dropdownCornerRadius)
        .overlay(
            RoundedRectangle(cornerRadius: dropdownCornerRadius)
                .stroke(Color.coreUIPrimary, lineWidth: 1)
        )
    }
}

struct DropdownButton: View {
    @State var shouldShowDropdown = false
    @Binding var displayText: String
    var options: [DropdownOption]
    var onSelect: ((_ key: String) -> Void)?

    let buttonHeight: CGFloat = 30
    var body: some View {
        Button(action: {
            self.shouldShowDropdown.toggle()
        }) {
            HStack {
                Text(displayText)
                Spacer()
                    .frame(width: 20)
                Image(systemName: self.shouldShowDropdown ? "chevron.up" : "chevron.down")
            }
        }
        .padding(.horizontal)
        .cornerRadius(dropdownCornerRadius)
        .frame(height: self.buttonHeight)
        .overlay(
            RoundedRectangle(cornerRadius: dropdownCornerRadius)
                .stroke(Color.coreUIPrimary, lineWidth: 1)
        )
        .overlay(
            VStack {
                if self.shouldShowDropdown {
                    Spacer(minLength: buttonHeight + 10)
                    Dropdown(options: self.options, onSelect: self.onSelect)
                }
            }, alignment: .topLeading
        )
        .background(
            RoundedRectangle(cornerRadius: dropdownCornerRadius).fill(Color.white)
        )
    }
}