-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathScaledFrame.swift
More file actions
127 lines (111 loc) · 3.58 KB
/
ScaledFrame.swift
File metadata and controls
127 lines (111 loc) · 3.58 KB
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import SwiftUI
extension View {
public func scaledFrame(width: CGFloat? = nil, height: CGFloat? = nil, alignment: Alignment = .center) -> some View {
ScaledFrameView(self, width: width, height: height, alignment: alignment)
}
/// Applies a scaled frame to the target view based on the current font scaling factor.
/// Use this function only when the target view requires dynamic scaling to adapt to font size changes.
public func scaledFrame(
minWidth: CGFloat? = nil,
idealWidth: CGFloat? = nil,
maxWidth: CGFloat? = nil,
minHeight: CGFloat? = nil,
idealHeight: CGFloat? = nil,
maxHeight: CGFloat? = nil,
alignment: Alignment = .center
) -> some View {
ScaledConstraintFrameView(
self,
minWidth: minWidth,
idealWidth: idealWidth,
maxWidth: maxWidth,
minHeight: minHeight,
idealHeight: idealHeight,
maxHeight: maxHeight,
alignment: alignment
)
}
}
struct ScaledFrameView<Content: View>: View {
let content: Content
let width: CGFloat?
let height: CGFloat?
let alignment: Alignment
@StateObject private var fontScaleManager = FontScaleManager.shared
var fontScale: Double {
fontScaleManager.currentScale
}
var scaledWidth: CGFloat? {
guard let width else {
return nil
}
return width * fontScale
}
var scaledHeight: CGFloat? {
guard let height else {
return nil
}
return height * fontScale
}
init(_ content: Content, width: CGFloat? = nil, height: CGFloat? = nil, alignment: Alignment = .center) {
self.content = content
self.width = width
self.height = height
self.alignment = alignment
}
var body: some View {
content
.frame(width: scaledWidth, height: scaledHeight, alignment: alignment)
}
}
struct ScaledConstraintFrameView<Content: View>: View {
let content: Content
let minWidth: CGFloat?
let idealWidth: CGFloat?
let maxWidth: CGFloat?
let minHeight: CGFloat?
let idealHeight: CGFloat?
let maxHeight: CGFloat?
let alignment: Alignment
@StateObject private var fontScaleManager = FontScaleManager.shared
var fontScale: Double {
fontScaleManager.currentScale
}
private func getScaledValue(_ v: CGFloat?) -> CGFloat? {
guard let v = v else {
return nil
}
return v * fontScale
}
init(
_ content: Content,
minWidth: CGFloat? = nil,
idealWidth: CGFloat? = nil,
maxWidth: CGFloat? = nil,
minHeight: CGFloat? = nil,
idealHeight: CGFloat? = nil,
maxHeight: CGFloat? = nil,
alignment: Alignment = .center
) {
self.content = content
self.minWidth = minWidth
self.idealWidth = idealWidth
self.maxWidth = maxWidth
self.minHeight = minHeight
self.idealHeight = idealHeight
self.maxHeight = maxHeight
self.alignment = alignment
}
var body: some View {
content
.frame(
minWidth: getScaledValue(minWidth),
idealWidth: getScaledValue(idealWidth),
maxWidth: getScaledValue(maxWidth),
minHeight: getScaledValue(minHeight),
idealHeight: getScaledValue(idealHeight),
maxHeight: getScaledValue(maxHeight),
alignment: alignment
)
}
}