我尝试重新实现我使用的SegmentedControlers,因为它们在Xcode 11 beta 5中已弃用。花了一段时间,但我得到了想要的外观。但是,当我用onTapGesture()替换tapAction时,选择器停止工作。
下面的代码显示了该问题。注释掉pickerStyle会得到一个与onTapGesture()一起工作的车轮捡拾器
import SwiftUI
var oneSelected = false
struct ContentView: View {
@State var sel = 0
var body: some View {
VStack {
Picker("Test", selection: $sel) {
Text("A").tag(0)
Text("B").tag(1)
Text("C").tag(2)
}
.pickerStyle(SegmentedPickerStyle())
Picker("Test", selection: $sel) {
Text("A").tag(0)
Text("B").tag(1)
Text("C").tag(2)
}
.pickerStyle(SegmentedPickerStyle())
.onTapGesture(perform: {
oneSelected = (self.sel == 1)
})
Text("Selected: \(sel)")
}
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
我希望Picker()。pickerStyle(SegmentedPickerStyle())的工作方式与SegmentedController()相同。
答案 0 :(得分:1)
您添加的tapGesture
会干扰选择器的内置点击手势识别,这就是为什么.onTapGesture
中的代码在选择器被点击时运行,但是选择器本身没有对点击做出响应的原因。对于您的情况,我建议采用另一种方法:将符合ObservableObject
的视图模型传递到您的ContentView
中,并使其包含一个@Published
变量供选择器选择。然后将属性观察器添加到该变量,以检查所选选项是否为1。
例如:
class ViewModel: ObservableObject {
@Published var sel = 0 {
didSet {
oneSelected = oldValue == 1
}
}
var oneSelected = false
}
在SceneDelegate.swift
或声明ContentView
的任何地方:
ContentView().environmentObject(ViewModel())
在ContentView.swift
中:
@EnvironmentObject var env: ViewModel
var body: some View {
VStack {
Picker("Test", selection: $env.sel) {
Text("A").tag(0)
Text("B").tag(1)
Text("C").tag(2)
}
.pickerStyle(SegmentedPickerStyle())
Picker("Test", selection: $env.sel) {
Text("A").tag(0)
Text("B").tag(1)
Text("C").tag(2)
}
.pickerStyle(SegmentedPickerStyle())
Text("Selected: \(sel)")
}
}
注意:根据我的经验,在以前的Beta中向SegmentedControl
添加tapGesture会导致SegmentedControl
无响应,所以我不确定为什么它能正常工作为您提供以前的版本。从SwiftUI beta 5开始,我认为尚无办法为手势分配优先级。
编辑:您可以使用.highPriorityGesture()
使手势优先于视图中定义的手势,但是优先级较高的手势会引起问题。但是,您可以使用.simultaneousGesture()
,我认为这可以解决您的问题,但是我认为它在SwiftUI Beta 5中并不能完全正常工作。
答案 1 :(得分:0)
class IndexManager: ObservableObject {
@Published var index = 0 {
didSet {
publisher.send(index)
}
}
let publisher = PassthroughSubject<Int, Never>()
}
struct SegmentedPickerView: View {
private let strings = ["a", "b", "c"]
@ObservedObject private var indexManager = IndexManager()
var body: some View {
Picker("", selection: $indexManager.index) {
ForEach(strings, id: \.self) {
Text($0).tag(self.strings.firstIndex(of: $0)!)
}
}.pickerStyle(SegmentedPickerStyle())
.onReceive(indexManager.publisher) { int in
print("onReceive \(int)")
}
}
}
答案 2 :(得分:0)
我能够在onTapGesture中以以下条件使用此功能
@State private var profileSegmentIndex = 0
Picker(selection: self.$profileSegmentIndex, label: Text("Music")) {
Text("My Posts").tag(0)
Text("Favorites").tag(1)
}
.onTapGesture {
if self.profileSegmentIndex == 0 {
self.profileSegmentIndex = 1
} else {
self.profileSegmentIndex = 0
}
}