Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import SwiftUI
- import Combine
- struct TierSelectorView: View {
- @State private var selectedRadioButton: Int? = nil
- let tiers: [String]
- var body: some View {
- VStack {
- ForEach(tiers.indices, id: \.self) { index in
- TierView(
- isSelected: Binding(
- get: { self.selectedRadioButton == index },
- set: { newValue in
- if newValue {
- self.selectedRadioButton = index
- }
- }
- ),
- label: tiers[index]
- )
- }
- }
- }
- }
- struct TierView: View {
- @Binding var isSelected: Bool
- let label: String
- var body: some View {
- HStack {
- TPRadioButton(isSelected: $isSelected, hasError: .constant(false))
- Text(label)
- }
- .padding()
- .background(Color.gray.opacity(0.2))
- .cornerRadius(8)
- }
- }
- struct ContentView: View {
- var body: some View {
- TierSelectorView(tiers: ["1", "2", "3"])
- }
- }
- public struct TPRadioButton: View {
- @StateObject private var viewModel: TPRadioButtonViewModel
- @Environment(\.isEnabled) private var isEnabled
- // Changed: Removed the viewModel initialization from init
- public init(isSelected: Binding<Bool>, hasError: Binding<Bool>) {
- self._viewModel = StateObject(wrappedValue: TPRadioButtonViewModel(isSelected: isSelected, hasError: hasError))
- }
- public var body: some View {
- if isEnabled && !viewModel.isDisabled {
- radioButton
- .onTapGesture {
- viewModel.select() // Changed: Updated the select function to toggle isSelected
- }
- } else {
- radioButton.mask(Color.white.opacity(0.3))
- }
- }
- }
- extension TPRadioButton {
- private var radioButton: some View {
- Circle()
- .fill(viewModel.isSelected ? Color.primary : Color.secondary)
- .frame(width: 16, height: 16)
- }
- }
- final class TPRadioButtonViewModel: ObservableObject {
- @Published var isSelected: Bool
- @Published var isPressed: Bool = false
- @Published var isDisabled: Bool = false
- @Published var hasError: Bool
- private var cancellables: Set<AnyCancellable> = []
- private var isSelectedBinding: Binding<Bool>
- init(isSelected: Binding<Bool>, hasError: Binding<Bool>) {
- self.isSelectedBinding = isSelected
- self.isSelected = isSelected.wrappedValue
- self.hasError = hasError.wrappedValue
- self.$isSelected.sink { value in
- DispatchQueue.main.async {
- isSelected.wrappedValue = value
- }
- }.store(in: &cancellables)
- self.$hasError.sink { value in
- DispatchQueue.main.async {
- hasError.wrappedValue = value
- }
- }.store(in: &cancellables)
- }
- func select() {
- DispatchQueue.main.async {
- self.isSelectedBinding.wrappedValue.toggle() // Changed: Toggled isSelected instead of setting it to true
- }
- }
- }
- struct OnPressViewModifier: ViewModifier {
- @Binding private var isPressed: Bool
- private let action: () -> Void
- init(isPressed: Binding<Bool>, action: @escaping () -> Void) {
- self._isPressed = isPressed
- self.action = action
- }
- func body(content: Content) -> some View {
- content
- .gesture(
- DragGesture(minimumDistance: 0)
- .onChanged { _ in
- self.isPressed = true
- }
- .onEnded { _ in
- self.isPressed = false
- self.action()
- }
- )
- }
- }
- extension View {
- func binding(isPressed: Binding<Bool>, action: @escaping () -> Void = {}) -> some View {
- modifier(OnPressViewModifier(isPressed: isPressed, action: action))
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement