我正在构建一个表单,并且想要实现一个选择器。 选择器应具有来自我的资产的普通图像以及文本。 在选择中,它工作正常,但如果没有选择,那就一团糟:
代码如下:
@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()
})
}
}
}
}
}
我错过了什么吗?在哪里可以限制选择器“预览”中的图像大小?
感谢您的帮助:)
如果我尝试使用 systemName-Image ,它会按预期工作。
也尝试过这个:
Image(uiImage: UIImage(imageLiteralResourceName: "d2"))
感谢您的帮助:)
查看 UI 层次结构,SwiftUI 似乎并不关心选择器中图像的
resizable
或 frame
修饰符。它只是将选择器转换为 UIButton
,图像作为按钮的图像,使用 UIImageView
显示。
这似乎不是我们可以控制的。也许我们能够在 SwiftUI 的未来版本中做到这一点。
一个简单的解决方案是制作较小版本的图像,以便它适合列表行。
如果由于某种原因您无法做到这一点,您可以尝试模仿
.menu
选择器的外观。
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)
}
}
}