taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

commit a49f1c38db7997bb9fb80468b92dae3cba82ba5f
parent 5d0072f0095dae9b5b8b76aefe2f04d1dac5fc60
Author: Marc Stibane <marc@taler.net>
Date:   Sun, 29 Oct 2023 12:27:29 +0100

Use AmountRowV

Diffstat:
MTalerWallet1/Views/Balances/BalanceRowView.swift | 79++++++++++++++++++-------------------------------------------------------------
MTalerWallet1/Views/Balances/PendingRowView.swift | 12++++++------
MTalerWallet1/Views/Balances/TwoRowButtons.swift | 22++++++++++++++--------
MTalerWallet1/Views/Exchange/ExchangeRowView.swift | 15++++++++-------
MTalerWallet1/Views/HelperViews/View+needVStack.swift | 53+++++++++++++++++++++++++++++++++++++----------------
5 files changed, 83 insertions(+), 98 deletions(-)

diff --git a/TalerWallet1/Views/Balances/BalanceRowView.swift b/TalerWallet1/Views/Balances/BalanceRowView.swift @@ -5,37 +5,9 @@ import SwiftUI import taler_swift -struct BalanceLabel: View { - let balanceTitle: String - let horizontal: Bool - let amountStr: String - let iconOnly: Bool - - var body: some View { - Group { // can either be horizontal (preferred) or vertical (if doesn't fit horizontally) - if !iconOnly { - Text(balanceTitle) - .accessibilityFont(.title2) - .foregroundColor(.secondary) - } - if horizontal { - Spacer(minLength: 0) - Text(amountStr) - .accessibilityFont(.title) - .monospacedDigit() - } else { HStack { - Spacer(minLength: 0) - Text(amountStr) - .accessibilityFont(.title) - .monospacedDigit() - } } - } - } -} - struct BalanceButton: View { let amountStr: String - let correctForSize: CGFloat + let sizeCategory: ContentSizeCategory let rowAction: () -> Void @AppStorage("iconOnly") var iconOnly: Bool = false @@ -48,16 +20,12 @@ struct BalanceButton: View { let titles = [(balanceTitle, TalerFont.uiFont(.title2)), (amountStr, TalerFont.uiFont(.title))] let needVStack = !iconOnly && Self.needVStack(titles, width: width, - correctForSize: correctForSize, - spacing: HSPACING, sameSize: false) - if needVStack { - VStack(alignment: .leading, spacing: 0) { - BalanceLabel(balanceTitle: balanceTitle, horizontal: false, amountStr: amountStr, iconOnly: iconOnly) - } - } else { - HStack(alignment: .lastTextBaseline, spacing: 0) { - BalanceLabel(balanceTitle: balanceTitle, horizontal: true, amountStr: amountStr, iconOnly: iconOnly) - } + sizeCategory: sizeCategory, + padding: 20, sameSize: false) + AmountRowV(amountStr: amountStr, largeAmountFont: true, fitsHorizontal: !needVStack) { + Text(iconOnly ? "" : balanceTitle) + .accessibilityFont(.title2) + .foregroundColor(.secondary) } } } @@ -91,23 +59,23 @@ struct BalanceRowView: View { VStack (alignment: .trailing) { let amountStr = currencyInfo?.string(for: amount.valueAsTuple) BalanceButton(amountStr: amountStr ?? amount.valueStr, - correctForSize: correctForSize, + sizeCategory: sizeCategory, rowAction: rowAction) let uiFont = TalerFont.uiFont(.title3) let titles = [(requestTitle1, uiFont), (requestTitle2, uiFont), (sendTitle1, uiFont), (sendTitle2, uiFont)] - let sendTitle = sendTitle1 + "\n" + sendTitle2 - let requestTitle = requestTitle1 + "\n" + requestTitle2 - let twoRowButtons = TwoRowButtons(sendTitle: sendTitle, recvTitle: requestTitle, - lineLimit: 5, sendDisabled: amount.isZero, - sendAction: sendAction, recvAction: recvAction) -// let _ = print("Screenwidth: \(UIScreen.screenWidth) Geometry: \(width) \(sizeCategory): \(sizeCategory)") - if Self.needVStack(titles, width: width, correctForSize: correctForSize, spacing: HSPACING) { + let needVStack = Self.needVStack(titles, width: width, sizeCategory: sizeCategory, padding: 10) + let twoRowButtons = TwoRowButtons(sendTitles: (sendTitle1, sendTitle2), + recvTitles: (requestTitle1, requestTitle2), + horizontal: needVStack, + lineLimit: 5, sendDisabled: amount.isZero, + sendAction: sendAction, + recvAction: recvAction) + if needVStack { VStack { twoRowButtons } } else { HStack(spacing: HSPACING) { twoRowButtons } } } -// .accessibilityElement(children: .combine) } } } @@ -115,28 +83,16 @@ struct BalanceRowView: View { #if DEBUG struct SomeBalanceRows: View { - @Environment(\.sizeCategory) var sizeCategory - var body: some View { let testInfo = PreviewCurrencyInfo(TESTCURRENCY, digits: 0) let demoInfo = PreviewCurrencyInfo(TESTCURRENCY, digits: 2) let test = try! Amount(fromString: TESTCURRENCY + ":1.23") - let demo = try! Amount(fromString: DEMOCURRENCY + ":1234.12") + let demo = try! Amount(fromString: DEMOCURRENCY + ":123.12") let testStr = testInfo.string(for: test.valueAsTuple) let demoStr = demoInfo.string(for: demo.valueAsTuple) - let correctForSize = Self.correctForSize(sizeCategory) - List { Section { - BalanceLabel(balanceTitle: "Balance:", horizontal: false, amountStr: demoStr, iconOnly: false) - .listRowSeparator(.hidden) - } - Section { - BalanceButton(amountStr: testStr, correctForSize: correctForSize, rowAction: {}) - .listRowSeparator(.hidden) - } - Section { BalanceRowView(amount: demo, currencyInfo: demoInfo, sendAction: {}, recvAction: {}, rowAction: {}) } BalanceRowView(amount: test, currencyInfo: testInfo, sendAction: {}, recvAction: {}, rowAction: {}) @@ -148,6 +104,7 @@ struct SomeBalanceRows: View { struct BalanceRowView_Previews: PreviewProvider { static var previews: some View { SomeBalanceRows() +// .environment(\.sizeCategory, .extraExtraLarge) Canvas Device Settings } } #endif diff --git a/TalerWallet1/Views/Balances/PendingRowView.swift b/TalerWallet1/Views/Balances/PendingRowView.swift @@ -19,13 +19,13 @@ struct InOrOutView: View { let imageWidth = image2.widthOfString(usingUIFont: imageFont) + 8.0 //.padding(.trailing) let title1Width = title1.widthOfString(usingUIFont: uiFont) let title2Width = title2.widthOfString(usingUIFont: uiFont) -// print("image: ", imageWidth, " title: ", max(title1Width, title2Width)) + print("image: ", imageWidth, " title: ", max(title1Width, title2Width)) return imageWidth + max(title1Width, title2Width) } var body: some View { let (title1, title2) = title - HStack(spacing: 0) { + HStack(spacing: 5) { let pendingColor = WalletColors().pendingColor(incoming) Image(systemName: imageName) .foregroundColor(pendingColor) @@ -46,9 +46,9 @@ struct PendingAmountView: View { let incoming: Bool public static func amountStr(amount: Amount, currencyInfo: CurrencyInfo?, incoming: Bool) -> String { - let sign = incoming ? "+ " : "- " +// let sign = incoming ? "+ " : "- " let amountStr = currencyInfo?.string(for: amount.valueAsTuple) - return sign + (amountStr ?? amount.valueStr) + return /*sign +*/ (amountStr ?? amount.valueStr) } public static func width(amount: Amount, currencyInfo: CurrencyInfo?, incoming: Bool) -> CGFloat { @@ -105,8 +105,8 @@ struct PendingRowView: View { } var body: some View { - let imageName = incoming ? "text.badge.plus" - : "text.badge.minus" + let imageName = incoming ? "plus.circle.fill" + : "minus.circle.fill" let imageStr = String("\(Image(systemName: imageName))") SingleAxisGeometryReader { width in Group { diff --git a/TalerWallet1/Views/Balances/TwoRowButtons.swift b/TalerWallet1/Views/Balances/TwoRowButtons.swift @@ -6,8 +6,9 @@ import SwiftUI import taler_swift struct TwoRowButtons: View { - let sendTitle: String - let recvTitle: String + let sendTitles: (String, String) + let recvTitles: (String, String) + let horizontal:Bool let lineLimit: Int let sendDisabled: Bool let sendAction: () -> Void @@ -15,14 +16,17 @@ struct TwoRowButtons: View { @Environment(\.sizeCategory) var sizeCategory var body: some View { + let delimiter = horizontal ? " " : "\n" + let (sendTitle1, sendTitle2) = sendTitles + let (recvTitle1, recvTitle2) = recvTitles Group { - Button(sendTitle, action: sendAction) + Button(sendTitle1 + delimiter + sendTitle2, action: sendAction) .lineLimit(lineLimit) .disabled(sendDisabled) .buttonStyle(TalerButtonStyle(type: .bordered, dimmed: false, aligned: .center)) - Button(recvTitle, action: recvAction) + Button(recvTitle1 + delimiter + recvTitle2, action: recvAction) .lineLimit(lineLimit) .disabled(false) .buttonStyle(TalerButtonStyle(type: .bordered, @@ -35,13 +39,15 @@ struct TwoRowButtons: View { struct TwoRowButtons_Previews: PreviewProvider { static var previews: some View { List { - TwoRowButtons(sendTitle: "Send\n" + TESTCURRENCY, - recvTitle: "Receive\n" + LONGCURRENCY, + TwoRowButtons(sendTitles: ("Send", TESTCURRENCY), + recvTitles: ("Receive", LONGCURRENCY), + horizontal: true, lineLimit: 2, sendDisabled: true, sendAction: {}, recvAction: {}) .listRowSeparator(.hidden) - TwoRowButtons(sendTitle: "Send\n" + DEMOCURRENCY, - recvTitle: "Receive\n" + DEMOCURRENCY, + TwoRowButtons(sendTitles: ("Send", DEMOCURRENCY), + recvTitles: ("Receive", DEMOCURRENCY), + horizontal: true, lineLimit: 2, sendDisabled: true, sendAction: {}, recvAction: {}) .listRowSeparator(.hidden) diff --git a/TalerWallet1/Views/Exchange/ExchangeRowView.swift b/TalerWallet1/Views/Exchange/ExchangeRowView.swift @@ -53,13 +53,14 @@ struct ExchangeRowView: View { Group { let uiFont = TalerFont.uiFont(.title3) let titles = [(depositTitle, uiFont), (withdrawTitle, uiFont), (currency, uiFont)] - let sendTitle = depositTitle + "\n" + currency // TODO: amount.currencyStr - let recvTitle = withdrawTitle + "\n" + currency // TODO: amount.currencyStr - let twoRowButtons = TwoRowButtons(sendTitle: sendTitle, recvTitle: recvTitle, - lineLimit: 5, sendDisabled: true, // TODO: amount.isZero - sendAction: { selectAndUpdate(1) }, - recvAction: { selectAndUpdate(2) }) - if Self.needVStack(titles, width: width, correctForSize: 1.0, spacing: HSPACING + 4) { + let needVStack = Self.needVStack(titles, width: width, sizeCategory: sizeCategory, padding: 10) + let twoRowButtons = TwoRowButtons(sendTitles: (depositTitle, currency), // TODO: amount.currencyStr + recvTitles: (withdrawTitle, currency), // TODO: amount.currencyStr + horizontal: needVStack, + lineLimit: 5, sendDisabled: true, // TODO: amount.isZero + sendAction: { selectAndUpdate(1) }, + recvAction: { selectAndUpdate(2) }) + if needVStack { VStack { twoRowButtons } } else { HStack(spacing: HSPACING) { twoRowButtons } diff --git a/TalerWallet1/Views/HelperViews/View+needVStack.swift b/TalerWallet1/Views/HelperViews/View+needVStack.swift @@ -10,20 +10,26 @@ extension View { /// returns true if any of the strings in 'titles' wouldn't fit in a view 1/'numViews' of the size of 'width', with 'spacing' /// if !sameSize then all titles are added with spacing static func needVStack(_ titles: [(String, UIFont)], - width: CGFloat, // total width available - correctForSize: CGFloat, - spacing: CGFloat, // between titles + width: CGFloat, // total width available + sizeCategory: ContentSizeCategory, + spacing: CGFloat = HSPACING, // between titles + padding: CGFloat = 20, sameSize: Bool = true, numViews: Int = 2) -> Bool { - let padding: CGFloat = 20 // TODO: depend on myListStyle + let correctForSize = correctForSize(sizeCategory) +// let padding = 20.0 // TODO: depend on myListStyle let totalSpacing = spacing * CGFloat(numViews - 1) var totalWidth = padding + totalSpacing - var maxTitleWidth: CGFloat = 0 - var minTitleWidth: CGFloat = 1000 + var maxTitleWidth = 0.0 + var minTitleWidth = 1000.0 for (title, uiFont) in titles { let titleWidth = title.widthOfString(usingUIFont: uiFont) + if width > 20 { + let widthStr = String(format: "%.2f * %.2f = %.2f", titleWidth, correctForSize, titleWidth * correctForSize) + print("❗️ \(title) \(widthStr)") + } let fixWidth = round(CGFloat(Int(20 * titleWidth * correctForSize))) / 20 if fixWidth > maxTitleWidth { maxTitleWidth = fixWidth @@ -35,27 +41,34 @@ extension View { } if sameSize { - let availableWidth = (width / CGFloat(numViews)) - totalSpacing + let availableWidth = width - totalSpacing + let singleWidth = availableWidth / CGFloat(numViews) let neededWidth = padding + maxTitleWidth -// if width > 20 { -// print("❗️ available: \(availableWidth) needed: \(neededWidth)") -// } - return neededWidth > availableWidth + if width > 20 { + let width1Str = String(format: "%.2f -spacing %.2f = %.2f / %d = %.2f", width, totalSpacing, + availableWidth, numViews, singleWidth) + let width2Str = String(format: "%.2f +padding %.2f = %.2f", maxTitleWidth, padding, maxTitleWidth + padding) + print("❗️ available: \(width1Str) needed: \(width2Str)") + } + return neededWidth > singleWidth } else { -// if width > 20 { + if width > 20 { + let totalStr = String(format: "%.2f -spacing %.2f = %.2f -padding %.2f = %.2f", totalWidth, totalSpacing, + totalWidth - totalSpacing, padding, totalWidth - totalSpacing - padding) + print("❗️ view width: \(width) total: \(totalStr)") // let (amount, font) = titles[1] -// print("❗️ view width: \(width) total: \(totalWidth) min: \(minTitleWidth) max: \(maxTitleWidth) \(amount)") -// } +// print("❗️ view width: \(width) total: \(totalStr) min: \(minTitleWidth) max: \(maxTitleWidth) \(amount)") + } return totalWidth > width } } static func correctForSize(_ sizeCategory: ContentSizeCategory) -> CGFloat { - return switch sizeCategory { + let corrValue = switch sizeCategory { case .extraSmall: 0.7 case .small: 0.8 case .medium: 0.9 - case .large: 1.0 +// case .large: 1.0 case .extraLarge: 1.15 case .extraExtraLarge: 1.25 case .extraExtraExtraLarge: 1.33 @@ -66,5 +79,13 @@ extension View { case .accessibilityExtraExtraExtraLarge: 2.5 default: 1.0 } + if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" { + // empirical values + return corrValue + } else { + // preview doesn't use ContentSizeCategory for widthOfString(usingUIFont) + // thus the empirical values are the square of what's really needed + return sqrt(corrValue) + } } }