Home > Software engineering >  Utilize buttons as pickers to pick between map views
Utilize buttons as pickers to pick between map views

Time:10-23

So I want to be able to utilize a picker so that I can choose between different views, but the only option that I found was a picker, which outputs the following output:

enter image description here

I want to have a custom solution where I can have three buttons, and choose between those similar to how a picker is chosen, here is the look that I'm attempting to achieve:

enter image description here

The code below renders the buttons perfectly, but the Picker don't render the contents of the button nor the modifiers, how would I be able to achieve clicking on each individual button similar to how a picker is selected?

The Picker also have a .tag(0), .tag(1) that can be utilized, how would this work on buttons?

Here is the code:

struct MapDisplaySheetView: View {
    
    @ObservedObject var mapSettings = MapSettings()
    @State var mapType = 0
    
    @State var allItems: [String] = [
        "Standard",
        "Hybrid",
        "Image",
    ]
    
    var body: some View {
        VStack(spacing: 0) {
            // MARK: Map Type
            HStack {
                Picker(
                    "Map Type",
                    selection: $mapType,
                    content: {
                        ForEach(allItems, id: \.self) { item in
                            VStack {
                                HStack {
                                    VStack {
                                        Text(item)
                                            .font(.footnote.weight(.bold))
                                            .frame(maxWidth: .infinity, alignment: .leading)
                                            .clipped()
                                            .foregroundColor(.primary)
                                    }
                                }
                                .padding(8)
                                .frame(maxWidth: .infinity, maxHeight: .infinity)
                                .clipped()
                            }
                            .border(.red)
                            .background {
                                RoundedRectangle(cornerRadius: 4, style: .continuous)
                                .foregroundColor(Color(.systemFill))
                            }
                            .foregroundColor(Color(.quaternaryLabel))
                            .cornerRadius(8)
                            .frame(maxWidth: .infinity, maxHeight: .infinity)
                            .clipped()
                        }
                    })
                .pickerStyle(SegmentedPickerStyle())
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
            .clipped()
            .padding(.bottom, 4)
        }
        .padding(16)
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .clipped()
    }
}

Here is what I attempted, but it's not working, I am not getting a log.info() output when clicking buttons:

struct MapDisplaySheetView: View {
    
    @ObservedObject var mapSettings = MapSettings()
    @State var mapType = 0
    
    @State var allItems: [String] = [
        "Standard",
        "Hybrid",
        "Image",
    ]
    
    var body: some View {
        VStack(spacing: 0) {
            HStack {
                ForEach(allItems, id: \.self) { item in
                    VStack {
                        HStack {
                            VStack {
                                Button(action: {
                                    // Action
                                }, label: {
                                    Text(item)
                                })
                                .tag(mapSettings.mapType)
                                .onChange(of: mapType) { newValue in
                                    mapSettings.mapType = newValue
                                    log.info("We have selected \(newValue)")
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

CodePudding user response:

you could try something like this:

struct MapDisplaySheetView: View {
    @ObservedObject var mapSettings = MapSettings()

    @State var allItems: [String] = ["Standard", "Hybrid", "Image"]
    
    var body: some View {
        HStack {
            ForEach(allItems, id: \.self) { item in
                    Button(action: {
                        mapSettings.mapType = item
                        print("We have selected \(item)")
                    }, label: {
                        Text(item)
                    })
                    .buttonStyle(.bordered)
                }
        }
    }
}

EDIT-1:

if the mapType is an Int, then use:

struct MapDisplaySheetView: View {
    @ObservedObject var mapSettings = MapSettings()

    @State var allItems: [String] = ["Standard", "Hybrid", "Image"]
    
    var body: some View {
        HStack {
            ForEach(allItems, id: \.self) { item in
                Button(action: {
                    switch item {
                      case "Standard": mapSettings.mapType = 0
                      case "Hybrid": mapSettings.mapType = 1
                      case "Image": mapSettings.mapType = 2
                      default: mapSettings.mapType = 0
                    }
                    print("We have selected \(item) mapSettings: \(mapSettings.mapType)  ")
                }, label: {
                    Text(item)
                })
                .buttonStyle(.bordered)
            }
        }
    }
}
  • Related