我想向 swiftui 选择器的标签添加一个按钮。
但按钮不可点击。
当我单击按钮时,选择器被单击。
如何使选择器仅在所选值的区域中单击?
按钮会接受他的点击?
import SwiftUI
enum Animal: String, CaseIterable, Identifiable {
case dog
case cat
case bird
var id: String { self.rawValue }
}
struct ContentView: View {
@State private var selectedAnimal = Animal.dog
var body: some View {
Form {
Group {
Section(header: Text("Animales")) {
VStack{
Picker(
selection: $selectedAnimal,
content: {
ForEach(Animal.allCases, id:\.self) {
Text($0.rawValue)
}},
label: {
HStack {
Text ("Chose Animale")
Spacer ()
Button (
action: {
print ("clicked")
},
label: {
Image(systemName: "arrow.clockwise")
})
Spacer ()
}
}
)
}
}
}
}
}
}
为了解决这个问题,我们需要将选择器和按钮分开,并阻止表单跟踪单击行内(默认情况下跟踪整行)。
对于第一个将按钮移出选择器并将所有内容放入
HStack
的情况,第二个我们需要一些技巧,例如标签上的 TapGesture 和按钮的非默认按钮样式(为简单起见,我使用了原始按钮样式,但最好创建自定义按钮)具有适当的突出显示等)
这是简化的更新和测试代码(Xcode 13 / iOS 15):
var body: some View {
Form {
Group {
Section(header: Text("Animales")) {
HStack{
HStack {
Text ("Chose Animale")
Spacer ()
}
.contentShape(Rectangle())
.onTapGesture {
// just blocker for label click
}
.overlay(
Button (
action: {
print ("clicked")
},
label: {
Image(systemName: "arrow.clockwise").foregroundColor(.blue)
})
.buttonStyle(PlainButtonStyle()) // << needed custom !!
)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.layoutPriority(1) // << to cover much area
//.border(Color.red) // << for testing area
Picker("",
selection: $selectedAnimal,
content: {
ForEach(Animal.allCases, id:\.self) {
Text($0.rawValue)
}}
)
.labelsHidden() // << hide own label
.fixedSize() // << limit size !!
}
.listRowInsets(EdgeInsets()) // << consume row space !!
}
}
}
}
只需在按钮下添加 .onTapGesture 并将操作移动到那里。
import SwiftUI
enum Animal: String, CaseIterable, Identifiable {
case dog
case cat
case bird
var id: String { self.rawValue }
}
struct ContentView: View {
@State private var selectedAnimal = Animal.dog
var body: some View {
Form {
Section (header: Text("Animales")) {
VStack {
Picker (selection: $selectedAnimal) {
ForEach(Animal.allCases, id:\.self) {
Text($0.rawValue)
}
} label: {
HStack {
Text ("Chose Animale")
Spacer ()
Button {} label: {
Image(systemName: "arrow.clockwise")
}
.onTapGesture {
print("clicked")
}
Spacer ()
}
}
}
}
}
}
}
#Preview {
ContentView()
}