【问题标题】:How to create Radiobuttons in SwiftUI?如何在 SwiftUI 中创建单选按钮?
【发布时间】:2020-12-16 23:45:13
【问题描述】:

我想对用户的选择做出反应。类似于此示例的内容:

在第二阶段,我想在每个单选按钮下方显示其他内容,例如将按钮 2 和 3 相互移动,以提供允许的网站列表。

到目前为止,我还没有找到如何在 SwiftUI 中执行此操作。 非常感谢!

【问题讨论】:

  • 到目前为止你有什么尝试?
  • 我只是在学习 SwiftUI,这是我的第一个需求。我的第一个想法是从头开始创建它,因为我找不到示例。现在我决定改用 Cocoa,因为我现在不能等太久。 :-(

标签: swiftui


【解决方案1】:
Picker(selection: $order.avocadoStyle, label: Text("Avocado:")) { 
    Text("Sliced").tag(AvocadoStyle.sliced) 
    Text("Mashed").tag(AvocadoStyle.mashed)
}.pickerStyle(RadioGroupPickerStyle())

这是 2019 年 swiftUI Essentials 主题演讲中的代码 (SwiftUI Essentials - WWDC 2019。他们在视频中大约 43 分钟展示了这个示例。

看起来像这样:

【讨论】:

  • 如何创建.radioGroup?
  • 这是一个预定义类型,但可以重命名为 RadioGroupPickerStyle。 .pickerStyle(RadioGroupPickerStyle())
  • 'RadioGroupPickerStyle' 已在此处明确标记为不可用 (SwiftUI.RadioGroupPickerStyle) 我遇到了错误
  • 我认为 iOS 本身不支持单选按钮。
  • 请注意 RadioGroupPickerStyle 仅在 Mac 上受支持(因此不支持 iOS)
【解决方案2】:

看看这个...一个易于使用的 iOS SwiftUI RadiobuttonGroup

你可以这样使用它:

RadioButtonGroup(items: ["Rome", "London", "Paris", "Berlin", "New York"], selectedId: "London") { selected in
                print("Selected is: \(selected)")
            }

这里是代码:

struct ColorInvert: ViewModifier {

    @Environment(\.colorScheme) var colorScheme

    func body(content: Content) -> some View {
        Group {
            if colorScheme == .dark {
                content.colorInvert()
            } else {
                content
            }
        }
    }
}

struct RadioButton: View {

    @Environment(\.colorScheme) var colorScheme

    let id: String
    let callback: (String)->()
    let selectedID : String
    let size: CGFloat
    let color: Color
    let textSize: CGFloat

    init(
        _ id: String,
        callback: @escaping (String)->(),
        selectedID: String,
        size: CGFloat = 20,
        color: Color = Color.primary,
        textSize: CGFloat = 14
        ) {
        self.id = id
        self.size = size
        self.color = color
        self.textSize = textSize
        self.selectedID = selectedID
        self.callback = callback
    }

    var body: some View {
        Button(action:{
            self.callback(self.id)
        }) {
            HStack(alignment: .center, spacing: 10) {
                Image(systemName: self.selectedID == self.id ? "largecircle.fill.circle" : "circle")
                    .renderingMode(.original)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: self.size, height: self.size)
                    .modifier(ColorInvert())
                Text(id)
                    .font(Font.system(size: textSize))
                Spacer()
            }.foregroundColor(self.color)
        }
        .foregroundColor(self.color)
    }
}

struct RadioButtonGroup: View {

    let items : [String]

    @State var selectedId: String = ""

    let callback: (String) -> ()

    var body: some View {
        VStack {
            ForEach(0..<items.count) { index in
                RadioButton(self.items[index], callback: self.radioGroupCallback, selectedID: self.selectedId)
            }
        }
    }

    func radioGroupCallback(id: String) {
        selectedId = id
        callback(id)
    }
}

struct ContentView: View {
    var body: some View {
        HStack {
            Text("Example")
                .font(Font.headline)
                .padding()
            RadioButtonGroup(items: ["Rome", "London", "Paris", "Berlin", "New York"], selectedId: "London") { selected in
                print("Selected is: \(selected)")
            }
        }.padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct ContentViewDark_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
        .environment(\.colorScheme, .dark)
        .darkModeFix()
    }
}

【讨论】:

    【解决方案3】:

    我刚刚编辑了@LizJ 答案,添加了Binding 而不是didTapActivedidTapInactive,所以它看起来像其他SwiftUI 元素

    import SwiftUI
    struct RadioButton: View {
        @Binding var checked: Bool    //the variable that determines if its checked
        
        var body: some View {
            Group{
                if checked {
                    ZStack{
                        Circle()
                            .fill(Color.blue)
                            .frame(width: 20, height: 20)
                        Circle()
                            .fill(Color.white)
                            .frame(width: 8, height: 8)
                    }.onTapGesture {self.checked = false}
                } else {
                    Circle()
                        .fill(Color.white)
                        .frame(width: 20, height: 20)
                        .overlay(Circle().stroke(Color.gray, lineWidth: 1))
                        .onTapGesture {self.checked = true}
                }
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      我正在使用 swift4、Catalina OS 和 Xcode 11.2,并且遇到了 RadioGroupPickerStyle 对 iOS 不可用且 .radiogroup 不起作用(它在构建中冻结)的问题,所以我自己制作了可在其他场合重复使用的问题。 (注意它只是一个按钮,所以你必须自己处理逻辑。)希望它有帮助!

      import SwiftUI
      
      struct RadioButton: View {
      let ifVariable: Bool    //the variable that determines if its checked
      let onTapToActive: ()-> Void//action when taped to activate
      let onTapToInactive: ()-> Void //action when taped to inactivate
      
      var body: some View {
          Group{
              if ifVariable {
                  ZStack{
                      Circle()
                          .fill(Color.blue)
                          .frame(width: 20, height: 20)
                      Circle()
                          .fill(Color.white)
                          .frame(width: 8, height: 8)
                  }.onTapGesture {self.onTapToInactive()}
              } else {
                  Circle()
                      .fill(Color.white)
                      .frame(width: 20, height: 20)
                      .overlay(Circle().stroke(Color.gray, lineWidth: 1))
                      .onTapGesture {self.onTapToActive()}
              }
          }
      }
      }
      

      使用:将它放在任何文件中,您就可以像在项目中的任何其他位置使用任何其他视图一样使用它。 (我们保留一个包含按钮文件的全局文件夹)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-03
        • 1970-01-01
        • 2020-09-13
        • 2014-04-30
        • 1970-01-01
        • 2021-11-17
        • 2016-11-25
        相关资源
        最近更新 更多