View+fitsSideBySide.swift (3516B)
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 import UIKit 10 11 extension View { 12 @MainActor 13 public func announce(_ this: String) { 14 if UIAccessibility.isVoiceOverRunning { 15 UIAccessibility.post(notification: .announcement, argument: this) 16 } 17 } 18 @MainActor 19 public func setVoice(to this: (any View)?) { 20 if UIAccessibility.isVoiceOverRunning { 21 UIAccessibility.post(notification: .layoutChanged, argument: this) 22 } 23 } 24 } 25 26 extension View { 27 /// if sameSize then this searches for the longest title 28 /// returns true if any of the strings in 'titles' wouldn't fit in a view 1/'numViews' of the size of 'width', with 'spacing' 29 /// if !sameSize then all titles are added with spacing 30 static func fitsSideBySide(_ titles: [(String, UIFont)], 31 availableWidth: CGFloat, // total width available 32 sizeCategory: ContentSizeCategory, 33 spacing: CGFloat = HSPACING, // between titles 34 padding: CGFloat = 20, 35 sameSize: Bool = true, 36 numViews: Int = 2) 37 -> Bool { 38 // let padding = 20.0 // TODO: depend on myListStyle 39 let totalSpacing = spacing * CGFloat(numViews - 1) 40 var totalWidth = padding + totalSpacing 41 42 var maxTitleWidth = 0.0 43 var minTitleWidth = 1000.0 44 for (title, uiFont) in titles { 45 let titleWidth = title.widthOfString(usingUIFont: uiFont, sizeCategory) 46 if titleWidth > maxTitleWidth { 47 maxTitleWidth = titleWidth 48 } 49 if titleWidth < minTitleWidth { 50 minTitleWidth = titleWidth 51 } 52 // if availableWidth > 20 { 53 // let widthStr = String(format: "%.2f + %.2f = %.2f", totalWidth, titleWidth, totalWidth + titleWidth) 54 // print("❗️ \(title) \(widthStr)") 55 // } 56 totalWidth += titleWidth 57 } 58 59 if sameSize { 60 let nettoWidth = availableWidth - totalSpacing 61 let singleWidth = nettoWidth / CGFloat(numViews) 62 let neededWidth = padding + maxTitleWidth 63 // if availableWidth > 20 { 64 // let width1Str = String(format: "%.2f -spacing %.2f = %.2f / %d = %.2f", availableWidth, totalSpacing, 65 // nettoWidth, numViews, singleWidth) 66 // let width2Str = String(format: "%.2f +padding %.2f = %.2f", maxTitleWidth, padding, maxTitleWidth + padding) 67 // print("❗️ available: \(width1Str) needed: \(width2Str)") 68 // } 69 return neededWidth < singleWidth 70 } else { 71 // if availableWidth > 20 { 72 // let totalStr = String(format: "%.2f -spacing %.2f = %.2f -padding %.2f = %.2f", totalWidth, totalSpacing, 73 // totalWidth - totalSpacing, padding, totalWidth - totalSpacing - padding) 74 // print("❗️ view width: \(availableWidth) total: \(totalStr)") 75 // let (amount, font) = titles[1] 76 // print("❗️ view width: \(width) total: \(totalStr) min: \(minTitleWidth) max: \(maxTitleWidth) \(amount)") 77 // } 78 return totalWidth < availableWidth 79 } 80 } 81 }