Home > Mobile >  How to expand SwiftUI picker options by external button click?
How to expand SwiftUI picker options by external button click?

Time:05-18

I am using SwiftUI Picker (MenuPickerStyle()). The options in the picker expands perfectly like the images below.

enter image description here

Code :

import SwiftUI

struct TestView: View {
    
    var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
    @State private var selectedMonth = ""
    
    var body: some View {
        
        Picker(selectedMonth, selection: $selectedMonth) {
            ForEach(months, id: \.self) {
                Text($0)
                   
            }
            
        }
        .frame(maxWidth: .infinity, alignment: .top)
        .pickerStyle(MenuPickerStyle())
        .foregroundColor(Color.black)
        .font(.custom("poppins_regular", size: 15))
    }
}

struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        TestView()
    }
}

But this only works when I click on the Picker.

Can I just expand it externally? (3rd screenshot)

Example : Can I expand it by a button click?

        Button("Click to expand picker options"){
            // Can I expand picker option by this Button click?
            
        }
        
        Picker(selectedMonth, selection: $selectedMonth) {
            ForEach(months, id: \.self) {
                Text($0)
                   
            }
            
        }
        .frame(maxWidth: .infinity, alignment: .top)
        .pickerStyle(MenuPickerStyle())
        .foregroundColor(Color.black)
        .font(.custom("poppins_regular", size: 15))
    } 

CodePudding user response:

Most likely not possible using native picker.

However, if stock controls functionality is limited or doesn't work as needed, make a new one and customize it as you like :)

struct MyPicker : View {

@Namespace var namespace

@Binding var values : [String]
@Binding var selected : String
@Binding var isExpanded : Bool

var body: some View {
    if isExpanded {
        List(values, id: \.self) { value in
            
            Text("\(value)")
                .foregroundColor(Color.black)
                .contentShape(Rectangle())
                .onTapGesture {
                    withAnimation {
                        selected = value
                        isExpanded.toggle()
                    }
                }
                
                .listRowBackground(selected == value ? Color.green.opacity(0.3) : Color.white)

            
        }.matchedGeometryEffect(id: "menu", in: namespace)
    } else {
        Text("\(selected != "" ? selected : values.first!)").padding()
            .frame(maxWidth: .infinity, alignment: .leading)
            
            .background(Rectangle().foregroundColor(.green.opacity(0.3)).cornerRadius(5))
            .matchedGeometryEffect(id: "menu", in: namespace)
            .foregroundColor(Color.black)
            .padding()

    }
        
}
}

stick it where you need it and customize as necessary.

struct PickerView: View {

@State var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
@State private var selectedMonth = "January"
@State var expanded : Bool = false

var body: some View {
    
    VStack {
        
        MyPicker(values: $months, selected: $selectedMonth, isExpanded: $expanded)
        .frame(maxWidth: .infinity, alignment: .top)
        .foregroundColor(Color.black)

        
        Button("Click to \(expanded ? "collapse" : "expand") picker options"){
            // Can I expand picker option by this Button click?
            withAnimation {
                expanded.toggle()
            }
        }.padding()

    }
    
}
}
  • Related