SegmentControl.swift (5616B)
1 /* 2 * This file is part of GNU Taler, ©2022-25 Taler Systems S.A. 3 * See LICENSE.md 4 */ 5 /** 6 * @author Marc Stibane 7 */ 8 import SwiftUI 9 10 struct SegmentControl: View { 11 @Binding var value: Int 12 let accountDetails: AccountDetailsArray 13 let action: (Int) -> Void 14 15 @Environment(\.colorScheme) private var colorScheme 16 @Environment(\.colorSchemeContrast) private var colorSchemeContrast 17 18 @State private var selectedAccount = 0 19 @ScaledMetric var frameHeight = 60 // relative to fontSize 20 21 public var body: some View { 22 let is26: Bool = if #available(iOS 26.0, *) { true } else { false } 23 let cornerRadius: CGFloat = is26 ? 16.0 : 6.0 24 let count = accountDetails.count 25 if count > 0 { 26 ZStack(alignment: .center) { 27 GeometryReader { geo in 28 RoundedRectangle(cornerRadius: cornerRadius) 29 .foregroundColor(WalletColors().pickerSelected(colorScheme, colorSchemeContrast)) 30 .cornerRadius(cornerRadius) 31 .padding(4) 32 .frame(width: geo.size.width / CGFloat(count)) 33 .offset(x: geo.size.width / CGFloat(count) * CGFloat(selectedAccount), y: 0) 34 } 35 .frame(height: frameHeight) 36 37 HStack(spacing: 0) { 38 ForEach((0..<count), id: \.self) { index in 39 let detail = accountDetails[index] 40 let specs = detail.currencySpecification 41 let scope = detail.scope 42 let amount = detail.transferAmount 43 let formatted = amount?.formatted(specs: specs, 44 isNegative: false, 45 scope: scope, 46 useISO: false) 47 ?? (EMPTYSTRING, EMPTYSTRING) 48 let bankName = detail.bankLabel 49 let a11yLabel = bankName != nil ? (bankName! + SPACE + formatted.1) 50 : formatted.1 51 // let _ = print(amountStr) 52 VStack(spacing: 6) { 53 Text(formatted.0) 54 .talerFont(.title3) 55 if let bankName { 56 Text(bankName) 57 .talerFont(.subheadline) 58 } 59 } 60 .accessibilityElement(children: .combine) 61 .accessibilityLabel(a11yLabel) 62 .accessibilityAddTraits(.isButton) 63 .accessibilityAddTraits(index == selectedAccount ? .isSelected : []) 64 .frame(maxWidth: .infinity) 65 .onTapGesture { 66 withAnimation(.easeInOut(duration: 0.150)) { 67 selectedAccount = index 68 } 69 } 70 } 71 } 72 } 73 .onAppear() { 74 if selectedAccount != value { 75 withAnimation { selectedAccount = value } 76 } 77 } 78 .onChange(of: selectedAccount) { selected in 79 action(selected) 80 } 81 .background( 82 RoundedRectangle(cornerRadius: cornerRadius) 83 .fill(WalletColors().sideBackgroundColor) 84 ) 85 } 86 } // body 87 } 88 89 struct SegmentControl2: View { 90 @Binding var value: Int 91 let strings: [String] 92 // let action: (Int) -> Void 93 94 @Environment(\.colorScheme) private var colorScheme 95 @Environment(\.colorSchemeContrast) private var colorSchemeContrast 96 97 public var body: some View { 98 let is26: Bool = if #available(iOS 26.0, *) { true } else { false } 99 let cornerRadius: CGFloat = is26 ? 16.0 : 6.0 100 let count = strings.count 101 if count > 0 { 102 ZStack(alignment: .center) { 103 GeometryReader { geo in 104 RoundedRectangle(cornerRadius: cornerRadius) 105 .foregroundColor(WalletColors().pickerSelected(colorScheme, colorSchemeContrast)) 106 .cornerRadius(cornerRadius) 107 .padding(4) 108 .frame(width: geo.size.width / CGFloat(count)) 109 .offset(x: geo.size.width / CGFloat(count) * CGFloat(value), y: 0) 110 } 111 112 HStack(spacing: 0) { 113 ForEach((0..<count), id: \.self) { index in 114 let string = strings[index] 115 VStack(spacing: 6) { 116 Text(string) 117 .talerFont(.title3) 118 } 119 .padding(.vertical, 8) 120 .accessibilityElement(children: .combine) 121 // .accessibilityLabel(a11yLabel) 122 .accessibilityAddTraits(.isButton) 123 .accessibilityAddTraits(index == value ? .isSelected : []) 124 .frame(maxWidth: .infinity) 125 .onTapGesture { 126 // action(index) 127 withAnimation(.easeInOut(duration: 0.150)) { 128 value = index 129 } 130 } 131 } 132 } 133 } 134 .background( 135 RoundedRectangle(cornerRadius: cornerRadius) 136 .fill(WalletColors().sideBackgroundColor) 137 ) 138 } 139 } // body 140 }