Advertisement
Milotronik

RadioButton2

Sep 22nd, 2024
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 4.08 KB | None | 0 0
  1. import SwiftUI
  2. import Combine
  3.  
  4. struct TierSelectorView: View {
  5.     @State private var selectedRadioButton: Int? = nil
  6.     let tiers: [String]
  7.  
  8.     var body: some View {
  9.         VStack {
  10.             ForEach(tiers.indices, id: \.self) { index in
  11.                 TierView(
  12.                     isSelected: Binding(
  13.                         get: { self.selectedRadioButton == index },
  14.                         set: { newValue in
  15.                             if newValue {
  16.                                 self.selectedRadioButton = index
  17.                             }
  18.                         }
  19.                     ),
  20.                     label: tiers[index]
  21.                 )
  22.             }
  23.         }
  24.     }
  25. }
  26.  
  27. struct TierView: View {
  28.     @Binding var isSelected: Bool
  29.     let label: String
  30.  
  31.     var body: some View {
  32.         HStack {
  33.             TPRadioButton(isSelected: $isSelected, hasError: .constant(false))
  34.             Text(label)
  35.         }
  36.         .padding()
  37.         .background(Color.gray.opacity(0.2))
  38.         .cornerRadius(8)
  39.     }
  40. }
  41.  
  42. struct ContentView: View {
  43.     var body: some View {
  44.         TierSelectorView(tiers: ["1", "2", "3"])
  45.     }
  46. }
  47.  
  48. public struct TPRadioButton: View {
  49.     @StateObject private var viewModel: TPRadioButtonViewModel
  50.     @Environment(\.isEnabled) private var isEnabled
  51.  
  52.     // Changed: Removed the viewModel initialization from init
  53.     public init(isSelected: Binding<Bool>, hasError: Binding<Bool>) {
  54.         self._viewModel = StateObject(wrappedValue: TPRadioButtonViewModel(isSelected: isSelected, hasError: hasError))
  55.     }
  56.  
  57.     public var body: some View {
  58.         if isEnabled && !viewModel.isDisabled {
  59.             radioButton
  60.                 .onTapGesture {
  61.                     viewModel.select() // Changed: Updated the select function to toggle isSelected
  62.                 }
  63.         } else {
  64.             radioButton.mask(Color.white.opacity(0.3))
  65.         }
  66.     }
  67. }
  68.  
  69. extension TPRadioButton {
  70.     private var radioButton: some View {
  71.         Circle()
  72.             .fill(viewModel.isSelected ? Color.primary : Color.secondary)
  73.             .frame(width: 16, height: 16)
  74.     }
  75. }
  76.  
  77. final class TPRadioButtonViewModel: ObservableObject {
  78.     @Published var isSelected: Bool
  79.     @Published var isPressed: Bool = false
  80.     @Published var isDisabled: Bool = false
  81.     @Published var hasError: Bool
  82.  
  83.     private var cancellables: Set<AnyCancellable> = []
  84.     private var isSelectedBinding: Binding<Bool>
  85.  
  86.     init(isSelected: Binding<Bool>, hasError: Binding<Bool>) {
  87.         self.isSelectedBinding = isSelected
  88.         self.isSelected = isSelected.wrappedValue
  89.         self.hasError = hasError.wrappedValue
  90.         self.$isSelected.sink { value in
  91.             DispatchQueue.main.async {
  92.                 isSelected.wrappedValue = value
  93.             }
  94.         }.store(in: &cancellables)
  95.         self.$hasError.sink { value in
  96.             DispatchQueue.main.async {
  97.                 hasError.wrappedValue = value
  98.             }
  99.         }.store(in: &cancellables)
  100.     }
  101.  
  102.     func select() {
  103.         DispatchQueue.main.async {
  104.             self.isSelectedBinding.wrappedValue.toggle() // Changed: Toggled isSelected instead of setting it to true
  105.         }
  106.     }
  107. }
  108.  
  109. struct OnPressViewModifier: ViewModifier {
  110.     @Binding private var isPressed: Bool
  111.     private let action: () -> Void
  112.  
  113.     init(isPressed: Binding<Bool>, action: @escaping () -> Void) {
  114.         self._isPressed = isPressed
  115.         self.action = action
  116.     }
  117.  
  118.     func body(content: Content) -> some View {
  119.         content
  120.             .gesture(
  121.                 DragGesture(minimumDistance: 0)
  122.                     .onChanged { _ in
  123.                         self.isPressed = true
  124.                     }
  125.                     .onEnded { _ in
  126.                         self.isPressed = false
  127.                         self.action()
  128.                     }
  129.             )
  130.     }
  131. }
  132.  
  133. extension View {
  134.     func binding(isPressed: Binding<Bool>, action: @escaping () -> Void = {}) -> some View {
  135.         modifier(OnPressViewModifier(isPressed: isPressed, action: action))
  136.     }
  137. }
  138.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement