Swiftui 带ONTAPPORATE的分段选择器';不要对轻叩声做出反应

Swiftui 带ONTAPPORATE的分段选择器';不要对轻叩声做出反应,swiftui,segmentedcontrol,Swiftui,Segmentedcontrol,我试图重新实现我正在使用的分段控制器,因为它们在Xcode 11 beta 5中被弃用了。花了一段时间,但我得到了我想要的样子。但是,当我用ontapsignature()替换tapAction时,选择器停止工作 下面的代码显示了问题。注释掉pickerStyle会得到一个车轮选择器,它可以与ontapsigner()一起工作 导入快捷界面 var oneSelected=false 结构ContentView:View{ @状态变量sel=0 var body:一些观点{ VStack{ 选择

我试图重新实现我正在使用的分段控制器,因为它们在Xcode 11 beta 5中被弃用了。花了一段时间,但我得到了我想要的样子。但是,当我用ontapsignature()替换tapAction时,选择器停止工作

下面的代码显示了问题。注释掉pickerStyle会得到一个车轮选择器,它可以与ontapsigner()一起工作

导入快捷界面
var oneSelected=false
结构ContentView:View{
@状态变量sel=0
var body:一些观点{
VStack{
选择器(“测试”,选择:$sel){
文本(“A”)。标记(0)
文本(“B”)。标签(1)
文本(“C”)。标签(2)
}
.pickerStyle(SegmentedPickerStyle())
选择器(“测试”,选择:$sel){
文本(“A”)。标记(0)
文本(“B”)。标签(1)
文本(“C”)。标签(2)
}
.pickerStyle(SegmentedPickerStyle())
.ONTAPPORATE(执行:{
oneSelected=(self.sel==1)
})
文本(“选定:\(选择)”)
}
}
}
#如果调试
结构内容视图\u预览:PreviewProvider{
静态var预览:一些视图{
ContentView()
}
}
#恩迪夫

我希望Picker().pickerStyle(SegmentedPickerStyle())的工作方式应该与SegmentedController()的工作方式相同。

您添加的
TapPasture
会干扰Picker内置的点击手势识别,这就是为什么当点击Picker时,
.ontapPasture
中的代码会运行的原因,但采摘器本身并没有对抽头做出反应。在您的情况下,我建议使用另一种方法:将符合
observeObject
的视图模型传递到
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中向
分段控件
添加点击手势会导致
分段控件
没有响应,因此我不确定为什么在以前的版本中它对您有效。从SwiftUI beta 5开始,我认为没有办法为手势指定优先级

编辑:您可以使用
.highpriority手势()
使您的手势优先于视图中定义的手势,但您的手势具有更高的优先级会导致您的问题。但是,您可以使用
.simultaneousposition()
,我认为这是您问题的解决方案,但我认为它在SwiftUI Beta 5中还没有完全发挥作用。

类索引管理器:ObservableObject{
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)")
        }
    }
}
@已发布的风险值指数=0{ 迪塞特{ publisher.send(索引) } } 让publisher=PassthroughSubject() } 结构分段PickerView:视图{ 私有let字符串=[“a”、“b”、“c”] @ObservedObject私有变量indexManager=indexManager() var body:一些观点{ 选择器(“,选择:$indexManager.index){ ForEach(字符串,id:\.self){ Text($0).tag(self.strings.firstIndex(of:$0)!) } }.pickerStyle(SegmentedPickerStyle()) .onReceive(indexManager.publisher){int in 打印(“onReceive\(int)”) } } }
我能够在以下条件下以ONTAPPORATE方式实现此功能

@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
                }
            }

我正计划做一些类似但更简单的事情。如果我去掉pickerStyle(),代码中的第二个选择器就会起作用,因此分段代码中的某些东西不起作用。可能是分段控件的代码具有不同的手势相关代码,因为视图需要知道用户在视图中点击的位置,在默认选择器中,不需要知道点击在视图中的位置。我们没有SwiftUI的源代码,因此无法确切了解分段控件选取器样式的点击手势识别的点击手势的优先级低于手动附加的点击手势的原因,但默认选取器并非如此。为了进一步说明这是一个与手势优先级相关的问题,如果向默认选取器添加轻触手势,则选取器会正确响应您的触摸,但手动添加的轻触手势不会被注册。在这种情况下,拾取者的手势识别优先于您手动添加的手势识别。如果没有SwiftUI源代码,我无法确切地告诉您原因。谢谢您的时间。我的解决方案是为Int创建一个包装器observeObject类,当Int更改值时调用闭包。现在我不需要担心水龙头了。@MichaelSalmon是的,没问题,这就是我的答案建议你走的路线。如果它是有帮助的和彻底的,你能接受这个答案吗?