Home > OS >  SVG Image asset not rending correctly inside Picker
SVG Image asset not rending correctly inside Picker

Time:10-07

I am running into an issue with SVG icons not resizing when used inside of a Picker.

By way of example, here is an example of using the SVG image assets in a basic list with the Picker commented out ...

struct DebugView: View {
    @State var selectedType: DrugOrMedicineType = .tablet
    var body: some View {
        VStack {
            List {
                //  Picker("Type", selection: $selectedType) {
                ForEach(DrugOrMedicineType.allCases, id: \.self) { t in
                    HStack {
                        Image(t.icon)
                            .resizable()
                            .scaledToFit()
                            .frame(width: 20, height: 20)
                        Text(t.title)
                        
                    }.tag(t)
                    
                }
                // }
                
            }
        }
    }
}

.. and this is what I see rendered ...

enter image description here

However, if I uncomment the Picker like this ...

struct DebugView: View {
    @State var selectedType: DrugOrMedicineType = .tablet
    var body: some View {
        VStack {
            List {
                Picker("Type", selection: $selectedType) {
                    ForEach(DrugOrMedicineType.allCases, id: \.self) { t in
                        HStack {
                            Image(t.icon)
                                .resizable()
                                .scaledToFit()
                                .frame(width: 20, height: 20)
                            Text(t.title)
                            
                        }.tag(t)
                        
                    }
                }
                
            }
        }
    }
}

I get this rendered ...

enter image description here

and this is what it looks like when I try to select from the list of options ...

enter image description here

Can someone explain why the image doesn't follow the HStack layout and respect the frame(...) modifier when it appears in the Picker?

NOTE I am using XCode 14.0.1 and running on iOS 16.

CodePudding user response:

Seems like they change the way that the label is handled in the picker compared to iOS 15, that's why you are having troubles with the label, this is a working example, using the label modifier you can handle the label the way you want:

                import SwiftUI

            enum PickerItems: String {
                case item1
                case item2
            }

            struct pickerView: View {
                @State var selected: PickerItems = .item1
                var body: some View {
                    
                    Menu {
                        Picker(selection: $selected,
                               label: EmptyView(),
                               content: {
                            HStack {
                                
                                Text("OPTION 1")
                                Image(systemName: "pencil")
                                    .resizable()
                                    .scaledToFit()
                                    .frame(width: 20, height: 20)
                            } .tag(PickerItems.item1)
                            
                            HStack {
                                Text("OPTION 2")
                                Image(systemName: "square.and.arrow.up.circle.fill")
                                    .resizable()
                                    .scaledToFit()
                                    .frame(width: 20, height: 20)
                                
                            }
                            .tag(PickerItems.item2)
                            
                            
                        }).pickerStyle(.automatic)
                            .accentColor(.white)
                    } label: {
                        Text("Selected Item: \(selected.rawValue)")
                            .font(.title3)
                    }
                }
            }

enter image description here

CodePudding user response:

It seems as though the Picker is broken in iOS 16. The best equivalent I could find was to use the Menu as was suggested by @guillermo-jiménez but leave out the Picker entirely.

Here is the result:

struct DebugView: View {
    @State var selectedType: DrugOrMedicineType = .tablet
    var body: some View {
        VStack {
            List {
                HStack {
                    Text("Type")
                    Spacer()
                    Menu {
                        ForEach(DrugOrMedicineType.allCases, id: \.self) { t in
                            Button {
                                selectedType = t
                            } label: {
                                Label(t.title, image: t.icon)
                            }
                        }
                    } label: {
                        HStack {
                            Image(selectedType.icon)
                                .resizable()
                                .scaledToFit()
                                .frame(width: 20, height: 20)
                            Text(selectedType.title)
                        }
                    }
                    
                }
                
            }
        }
    }
}

This is how it looks as and item in the list ...

enter image description here

... and this is how it looks when you make a selection:

enter image description here

  • Related