2

I am building a Form right know and want to implement a Picker. The Picker shall have a normal Image from my Assets plus the Text. In the selection, it works fine, but without selection, is's a mess:

enter image description here

Code below:

    
    @State private var name = ""
    @State private var careTypeName = "Prune"
    @State private var careDue = Date.now
    @State private var datePickerId: Int = 0
    @State private var selectedBonsai = "Juniperus"
    @State private var selectedBonsai2 = 0
    
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        NavigationView {
            Form {
                Section("Choose either a Taskname or pick Careoption") {
                    TextField("Taskname", text: $name)
                    Picker("Care option", selection: $careTypeName) {
                                ForEach(["Prune", "Watering", "Fertilize"], id: \.self) { subject in
                                  Text(subject)
                                }
                              }
                }
                Section("Pick a date for Task") {
                    DatePicker(selection: $careDue, in: ...Date.now, displayedComponents: .date) {
                        Text("Select a due date")
                    }
                    .id(datePickerId)
                    .onChange(of: careDue, perform: { _ in
                      datePickerId += 1
                    })
                    
                }
                Section("Select Bonsai:") {
                    Picker(selection: $selectedBonsai, label: Text("Bonsai")) {
                        HStack {
                            Image("d2")
                                .renderingMode(Image.TemplateRenderingMode.original)
                                .resizable()
                                .scaledToFill()
                                .frame(maxWidth: 60, maxHeight: 35)
                                .clipShape(RoundedRectangle(cornerRadius: 3))
                            
                            Text(selectedBonsai)
                            
                        }
                    }
                }
                
                Button {
                    dismiss()
                } label: {
                    HStack {
                        Spacer()
                        Text("Save Task")
                            .foregroundColor(Color("buttonColor"))
                        Spacer()
                    }
                }

            }
            .navigationBarTitleDisplayMode(.inline)
                    .toolbar {
                        ToolbarItem(placement: .topBarLeading) {
                            VStack {
                                Text("Add Task")
                                  .font(.system(size: 25))
                                  .bold()
                                  .foregroundColor(Color("titleColor"))
                            }.padding(.leading, 8)
                        }
                        ToolbarItem(placement: .topBarTrailing) {
                            Button(action: {
                                dismiss()
                            }, label: {
                                Text("Cancel")
                                    .foregroundColor(Color("headerButtons"))
                                    .bold()
                            })
                        }
                    }
            
        }
            
    }
}

Did I miss something? Where can I restrict the image-size in the "preview" from the Picker?

Thanks for help :)

If I'm try it with a systemName-Image it works as intended. enter image description here

Tried this as well: Image(uiImage: UIImage(imageLiteralResourceName: "d2"))

Thanks for help :)

2
  • AFAIK, you need to include a small icon size version of your picture "d2" in your Assets.xcassets Commented Oct 20, 2023 at 2:11
  • Sure, I could do that, but images will be generated by User later and I am working with SwiftData later on. Let's say, someone has 50 trees, that would mean the app would save 100 images in the storage. This could be a solution later, if I hook the app to iCloud. But thanks for you suggestion anyway! Commented Oct 20, 2023 at 6:06

1 Answer 1

3

Looking at the UI hierarchy, it appears that SwiftUI doesn't care about resizable or frame modifiers for images in the picker. It just translates the picker into a UIButton, with the image as the button's image, which is displayed using a UIImageView.

This doesn't seem like something we can control. Perhaps we will be able to do that in a future version of SwiftUI.

A simple solution is to just make a smaller version of the image, so that it fits into the list row.

If you cannot do that for some reason, you can try to mimic how a .menu picker looks.

LabeledContent("Bonsai") {
    HStack {
        Image("d2") // putting the image of the currently selected option outside of the picker
        // in reality you would do Image(f(selectedBonsai)) where f is a function
        // that converts the selected option to an image name
            .renderingMode(Image.TemplateRenderingMode.original)
            .resizable()
            .scaledToFit()
            .frame(maxWidth: 60, maxHeight: 35)
            .clipShape(RoundedRectangle(cornerRadius: 3))
        Menu {
            // put the picker inside a menu, so users see the images in the menu
            Picker(selection: $selectedBonsai) {
                Label {
                    Text(selectedBonsai)
                } icon: {
                    Image("my_image")
                }
                .tag("Juniperus")
            } label: { }
        } label: {
            HStack {
                Text(selectedBonsai)
                Image(systemName: "chevron.up.chevron.down")
            }
            .tint(.secondary)
            .imageScale(.small)
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I have tried it and I looks exactly as it should! Later I can easily loop through the database and the function for the image should'nt be that hard. THANKS!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.