簡體   English   中英

SwiftUI:如何在 SwiftUI 中實現單選按鈕

[英]SwiftUI: How to implement Radio button in SwiftUI

我正在創建一個簡單的表單應用程序。 在那,我有復選框和單選按鈕,但我不知道該怎么做。

我已經完成了以下代碼來動態更改所選選項的顏色。 但它可以是 select 多個值。 我只需要 select 5 個值中的一個值,例如單選按鈕。

例如:我正在點擊第二個單選按鈕。 現在如果我 select 第四個單選按鈕,第二個應該取消選擇,第四個應該被選中。


struct DCTableCell: View {

    @Binding var dcValue: String

    @State var isSelected: Bool = false

    var body: some View {


        Button(action: {
            print("Tapped")
            self.isSelected.toggle()
        }){
            ZStack {
                RoundedRectangle(cornerRadius: 8)
                    .stroke(self.isSelected ? Color.init("borderSelected"): Color.init("border"))
                    .frame(height: 56)
                    .foregroundColor(.clear)

                HStack {
                    Text(dcValue)
                        .font(.custom("Montserrat", size: 16))
                        .fontWeight(.medium)
                        .foregroundColor(self.isSelected ? Color.init("borderSelected") : .white)
                        .padding()

                    Spacer()

                    ZStack {
                        Circle()
                            .stroke(self.isSelected ? Color.init("borderSelected") : Color("circleBorder"))
                            .frame(width: 18, height: 18)
                            .padding()

                        Circle()
                            .frame(width: 10, height: 10)
                            .foregroundColor(self.isSelected ? Color.init("borderSelected"): Color.clear)

                    }
                }
            }
        }
    }
}

看看這個...一個易於使用的 SwiftUI RadiobuttonGroup 用於 iOS

你可以像這樣使用它:

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()
    }
}

在此處輸入圖像描述

好的,這不是一個理想的解決方案,但它可以工作,並希望讓您大開眼界,以改善您所擁有的。 我給每個 RadioButton 一個 ID,當所選 ID 更改時,它會更新:

struct DCTableCell: View {

    var id: Int
    @Binding var dcValue: String
    @Binding var selectedID: Int

    var body: some View {
        Button(action: {
            print("Tapped")
            self.selectedID = self.id
        }){
            ZStack {
                RoundedRectangle(cornerRadius: 8)
                    .stroke(self.id == self.selectedID ? Color.blue : Color.white)
                    .frame(height: 56)
                    .foregroundColor(.clear)

                HStack {
                    Text(dcValue)
                        .font(.custom("Montserrat", size: 16))
                        .fontWeight(.medium)
                        .foregroundColor(self.id == self.selectedID ? .blue : .white)
                        .padding()

                    Spacer()

                    ZStack {
                        Circle()
                            .stroke(self.id == self.selectedID ? Color.blue : .black)
                            .frame(width: 18, height: 18)
                            .padding()

                        Circle()
                            .frame(width: 10, height: 10)
                            .foregroundColor(self.id == self.selectedID ? Color.blue: Color.clear)

                    }
                }
            }
        }
    }
}

以及如何使用它。 也許您應該創建一個包含 id 和要傳入的字符串的數組。

struct ContentView: View {
    @State var str = "lolz"
    @State var selectedID = -1

    var body: some View {
        VStack {
            ForEach((1...5), id: \.self) { index in
                DCTableCell(id: index, dcValue: self.$str, selectedID: self.$selectedID)
            }
        }
    }
}

我希望這有幫助!

我有一個類似的解決方案,將標簽用作可散列標簽,使其非常直接。 所以你只需要設置外層: CustomDCPicker ,就像一個通用的選擇器。

                 UIHostingController(rootView: CustomDCPicker())

        struct CustomDCPicker: View {
            @State var dcValue: String = ""
            var body: some View {
                VStack{
                    Text(dcValue).bold()
                    DCTable.init(dcValue: $dcValue, Labels: ["sample1","sample2","sample3","sample4","sample5"])
                }
            }
        }

        struct DCTable: View {
            @Binding var dcValue: String
            var Labels: [String] = []
        var body: some View {
            ForEach(Labels, id:\.self){
                DCTableCell(dcValue: self.$dcValue, myLabel: $0)
            }
        }
        }

        struct DCTableCell: View {
            @Binding var dcValue: String
            var isSelected: Bool {
                get{   self.dcValue == self.myLabel}
            }
            var myLabel : String
            var body: some View {
                Button(action: {
                    print("Tapped")
                    self.dcValue = self.myLabel
                }){
                    ZStack {
                        RoundedRectangle(cornerRadius: 8.0)
                            .stroke(self.isSelected ? Color.red: Color.yellow)
                            .frame(height: 56)
                            .foregroundColor(.clear)

                        HStack {
                            Text(myLabel)
                                //.font(.custom("Montserrat", size: 16))
                                .fontWeight(.medium)
                                .foregroundColor(self.isSelected ? Color.red : .black)
                                .padding()

                            Spacer()

                            ZStack {
                                Circle()
                                    .stroke(self.isSelected ? Color.red : Color.black)
                                    .frame(width: 18, height: 18)
                                    .padding()

                                Circle()
                                    .frame(width: 10, height: 10)
                                    .foregroundColor(self.isSelected ? Color.red: Color.clear)

                            }
                        }
                    }
                }
            }
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM