summaryrefslogtreecommitdiff
path: root/TalerWallet1/Helper/TalerStrings.swift
blob: 64fb58a31680c4e52f5b772055ffb81d8eb8feb7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
 * This file is part of GNU Taler, ©2022-23 Taler Systems S.A.
 * See LICENSE.md
 */
import SwiftUI
import Foundation
import UIKit

extension StringProtocol {
    func trimURL() -> String {
        if let url = URL(string: String(self)) {
            if let host = url.host {
                return host
            }
        }
        return String(self)
    }

    func index<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> Index? {
        range(of: string, options: options)?.lowerBound
    }
    func endIndex<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> Index? {
        range(of: string, options: options)?.upperBound
    }
    func indices<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> [Index] {
        ranges(of: string, options: options).map(\.lowerBound)
    }
    func ranges<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> [Range<Index>] {
        var result: [Range<Index>] = []
        var startIndex = self.startIndex
        while startIndex < endIndex,
              let range = self[startIndex...]
            .range(of: string, options: options) {
            result.append(range)
            startIndex = range.lowerBound < range.upperBound ? range.upperBound :
            index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
        }
        return result
    }
}

extension String {
    func widthOfString(usingUIFont font: UIFont) -> CGFloat {
        let fontAttributes = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttributes)
        return size.width
    }

    func widthOfString(usingUIFont font: UIFont, _ sizeCategory: ContentSizeCategory) -> CGFloat {
        let width = widthOfString(usingUIFont: font)
        let correctForSize = correctForSize(sizeCategory)

        return width * correctForSize
    }

    // This would be used like so:
    // let uiFont = UIFont.systemFont(ofSize: 17, weight: .bold)
    // let width = "SomeString".widthOfString(usingUIFont: uiFont)

    ///
    fileprivate func correctForSize(_ sizeCategory: ContentSizeCategory) -> CGFloat {
        let corrValue = switch sizeCategory {
            case .extraSmall: 0.7
            case .small: 0.8
            case .medium: 0.9
//            case .large: 1.0
            case .extraLarge: 1.15
            case .extraExtraLarge: 1.25
            case .extraExtraExtraLarge: 1.33
            case .accessibilityMedium: 1.52
            case .accessibilityLarge: 1.8
            case .accessibilityExtraLarge: 2.0
            case .accessibilityExtraExtraLarge: 2.2
            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)
        }
    }
}