SwiftUI Segmented Picker 在点击时不会切换

Posted

技术标签:

【中文标题】SwiftUI Segmented Picker 在点击时不会切换【英文标题】:SwiftUI Segmented Picker does not switch when click on it 【发布时间】:2020-05-26 15:30:52 【问题描述】:

我正在尝试使用 SwiftUI 实现分段控制。由于某种原因,分段选择器在单击时不会在值之间切换。我浏览了许多教程,但找不到与我的代码有任何区别:

struct MeetingLogin: View 
    @State private var selectorIndex: Int = 0

    init() 
        UISegmentedControl.appearance().backgroundColor = UIColor(named: "JobsLightGreen")
        UISegmentedControl.appearance().selectedSegmentTintColor = UIColor(named: "AlmostBlack")
        UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white,
                                                                .font: UIFont(name: "OpenSans-Bold", size: 13)!],
                                                               for: .selected)
        UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white,
                                                                .font: UIFont(name: "OpenSans-Regular", size: 13)!],
                                                               for: .normal)
    

    var body: some View 
        VStack 

            ...

            Group 
                Spacer().frame(minHeight: 8, maxHeight: 30)
                Picker("video", selection: $selectorIndex) 
                    Text("Video On").tag(0)
                    Text("Video Off").tag(1)
                
                .pickerStyle(SegmentedPickerStyle())
                .padding([.leading, .trailing], 16)

                Spacer().frame(minHeight: 8, maxHeight: 50)
                Button(action:  self.sendPressed() ) 
                    ZStack 
                        RoundedRectangle(cornerRadius: 100)
                        Text("go")
                            .font(.custom("Roboto-Bold", size: 36))
                            .foregroundColor(Color("MeetingGreen"))
                    
                
                .foregroundColor(Color("MeetingLightGreen").opacity(0.45))
                .frame(width: 137, height: 73)
            
            Spacer()
        
    

希望有任何建议!

【问题讨论】:

【参考方案1】:

更新:问题似乎是由于 View 的重叠而发生的,因为 RoundedRectangle 的cornerRadius 值设置为 100。将cornerRadius 的值设置为 55 将恢复 Picker 的功能。

这个问题似乎是由ZStack 中的RoundedRectangle(cornerRadius: 100) 引起的。我没有解释为什么会这样。如果我发现了,我会添加原因。可能是 SwiftUI 错误。在找到任何相关证据之前我无法确定。所以这是可以使SegmentedControl 正常工作的代码。

struct MeetingLogin: View 
    //...
    @State private var selectorIndex: Int = 0

    var body: some View 
        VStack 
            //...
            Group 
                Spacer().frame(minHeight: 8, maxHeight: 30)
                Picker("video", selection: $selectorIndex) 
                    Text("Video On").tag(0)
                    Text("Video Off").tag(1)
                
                .pickerStyle(SegmentedPickerStyle())
                .padding([.leading, .trailing], 16)

                Spacer().frame(minHeight: 8, maxHeight: 50)
                Button(action:  self.sendPressed() ) 
                    ZStack 
                        RoundedRectangle(cornerRadius: 55)
                        Text("go")
                            .font(.custom("Roboto-Bold", size: 36))
                            .foregroundColor(Color("MeetingGreen"))
                    
                
                .foregroundColor(Color("MeetingLightGreen").opacity(0.45))
                .frame(width: 137, height: 73)
            
            Spacer()
        
    

【讨论】:

哇,真是奇怪的东西!谢谢你的帮助! @dandepeched 是的,我也这么认为。我投了赞成票,以便这篇文章得到一些关注。 进一步调查表明问题出在cornerRaduis值上。当它设置为 50 时,Picker 工作正常,并且按钮看起来完全一样(因为帧长宽比)。所以我相信这是 UI 重叠或类似的一些错误。请将此信息添加到您的答案中。 是的,水龙头正在 RoundedRectangle 上注册。【参考方案2】:

Xcode 12 ios 14 您可以通过在 Segment Control(Picker) 的 tapGesture 上添加 if-else 条件来获取它

@State private var profileSegmentIndex = 0
Picker(selection: self.$profileSegmentIndex, label: Text("Jamaica")) 
                    Text("My Posts").tag(0)
                
                Text("Favorites").tag(1)
            
            .onTapGesture 
                if self.profileSegmentIndex == 0 
                    self.profileSegmentIndex = 1
                 else 
                    self.profileSegmentIndex = 0
                
            
            .pickerStyle(SegmentedPickerStyle())
            .padding()

如果您需要将它与 2 个以上的段一起使用,您可以尝试使用 Enum :)

【讨论】:

【参考方案3】:

您的代码/视图缺少 if 条件以了解当 selectorIndex 为 0 或 1 时会发生什么。

它必须看起来像这样:

var body: some View 

    VStack 
        if selectorIndex == 0 
    //....Your VideoOn-View 
     else 
    //Your VideoOff-View
    

【讨论】:

不,SwiftUI Picker 不需要 'if' 条件 Huhlemann 建议使用选定的选择器索引在选择特定索引时有条件地显示视图。他是对的。也许他可以在他的示例中包含有效的选择器代码,但他的观点是正确的,那么为什么要对他投反对票呢? 他的提议与这个特定问题无关。

以上是关于SwiftUI Segmented Picker 在点击时不会切换的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:使用 Picker(分段)更改 ForEach 源或获取请求

SwiftUI Segmented Control 在视图刷新时选择段文本动画

SwiftUI 中的一排 Picker ***,为啥拖动滚动区域从屏幕上的 Picker 控件偏移?

SwiftUI 为啥 Picker 上的输入不起作用?

SwiftUI:以编程方式设置 Picker 的值

在 SwiftUI 的 Picker 中添加新元素