SwiftUI 自定義RadioButton

系統(tǒng)CheckBox(Toggle組件)開關(guān)無法改造,系統(tǒng)提供的Picker組件可以采用RadioGroupPickerStyle()來實現(xiàn)單選,但UI過于單一。需要單選按鈕可以分組且選中和非選中icon可自定義方便擴(kuò)展,直接上代碼

RadioButton.swift
import Foundation
import SwiftUI

public struct RadioButton<Image, Label> : View where Image : View, Label : View {
    
    let id: String
    @Binding var selectedId: String
    
    @ViewBuilder var image: (Bool) -> Image
    @ViewBuilder var label: () -> Label
    
    public init(id: String, selectedId: Binding<String>, @ViewBuilder image: @escaping (Bool) -> Image, @ViewBuilder label: @escaping () -> Label) {
        self.id = id;
        self._selectedId = selectedId
        self.image = image
        self.label = label
    }
    
    public var body: some View {
        Button {
            self.selectedId = id
        } label: {
            HStack {
                image(id == self.selectedId)
                label()
            }
            .contentShape(Rectangle())
        }
        .buttonStyle(.plain)
    }
}
調(diào)用舉例
@State private var radioSelected: String = "0" //獲取選中值且起到分組作用
@State private var radioSelected2: String = "0"

var body: some View {
  VStack(spacing: 10) {

  //===================組一

    RadioButton(id: "0", selectedId: $radioSelected) { check in
      Image(systemName: check ? "record.circle.fill" : "circle")
        .resizable()
        .aspectRatio(contentMode: .fit)
        .frame(width: 14, height: 14, alignment: .center)
        .foregroundColor(check ? Color.accentColor : Color.gray)
    } label: {
      Text("選項A")
        .font(.system(size: 14))
    }
    
    RadioButton(id: "1", selectedId: $radioSelected) { check in
      Image(systemName: check ? "record.circle.fill" : "circle")
        .resizable()
        .aspectRatio(contentMode: .fit)
        .frame(width: 14, height: 14, alignment: .center)
        .foregroundColor(check ? Color.accentColor : Color.gray)
    } label: {
      Text("選項B")
        .font(.system(size: 14))
    }

  //===================組二

    RadioButton(id: "0", selectedId: $radioSelected2) { check in
      Image(systemName: check ? "checkmark.circle.fill" : "circle")
        .resizable()
        .aspectRatio(contentMode: .fit)
        .frame(width: 14, height: 14, alignment: .center)
        .foregroundColor(check ? Color.accentColor : Color.gray)
    } label: {
      Text("選項A")
        .font(.system(size: 14))
    }

   RadioButton(id: "1", selectedId: $radioSelected2) { check in
      Image(systemName: check ? "checkmark.circle.fill" : "circle")
        .resizable()
        .aspectRatio(contentMode: .fit)
        .frame(width: 14, height: 14, alignment: .center)
        .foregroundColor(check ? Color.accentColor : Color.gray)
    } label: {
      Text("選項B")
        .font(.system(size: 14))
    }
  
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容