@@ -26,11 +26,11 @@ class TabViewProps: ObservableObject {
26
26
*/
27
27
struct RepresentableView : UIViewRepresentable {
28
28
var view : UIView
29
-
29
+
30
30
func makeUIView( context: Context ) -> UIView {
31
31
return view
32
32
}
33
-
33
+
34
34
func updateUIView( _ uiView: UIView , context: Context ) { }
35
35
}
36
36
@@ -40,7 +40,7 @@ struct RepresentableView: UIViewRepresentable {
40
40
struct TabViewImpl : View {
41
41
@ObservedObject var props : TabViewProps
42
42
var onSelect : ( _ key: String ) -> Void
43
-
43
+
44
44
var selectedActiveTintColor : UIColor ? {
45
45
// check first in selected tab
46
46
let selectedPage = props. selectedPage
@@ -51,21 +51,21 @@ struct TabViewImpl: View {
51
51
}
52
52
}
53
53
}
54
-
54
+
55
55
if let activeTintColor = props. activeTintColor {
56
56
return activeTintColor
57
57
}
58
-
58
+
59
59
return nil
60
60
}
61
-
61
+
62
62
var body : some View {
63
63
TabView ( selection: $props. selectedPage) {
64
64
ForEach ( props. children? . indices ?? 0 ..< 0 , id: \. self) { index in
65
65
let child = props. children ? [ safe: index] ?? UIView ( )
66
66
let tabData = props. items? . tabs [ safe: index]
67
67
let icon = props. icons [ index]
68
-
68
+
69
69
RepresentableView ( view: child)
70
70
. ignoresTopSafeArea (
71
71
props. ignoresTopSafeArea ?? false ,
@@ -92,37 +92,31 @@ struct TabViewImpl: View {
92
92
UIView . setAnimationsEnabled ( true )
93
93
}
94
94
}
95
-
96
- // to apply active tint color per tab
97
- let scrollEdgeAppearance = configureAppearance ( for: props. scrollEdgeAppearance ?? " " )
98
- let colorTintAppearance = configureAppearance ( appearance: scrollEdgeAppearance, inactiveTint: props. inactiveTintColor, activeTint: selectedActiveTintColor)
99
- setupTabBarAppearance ( colorTintAppearance)
100
-
95
+
101
96
onSelect ( newValue)
102
97
}
103
98
. onAppear ( ) {
104
- updateTabBarAppearance ( props: props)
99
+ updateTabBarAppearance ( props: props, selectedActiveTintColor : selectedActiveTintColor )
105
100
}
106
101
. onChange ( of: props. barTintColor) { newValue in
107
- updateTabBarAppearance ( props: props)
102
+ updateTabBarAppearance ( props: props, selectedActiveTintColor : selectedActiveTintColor )
108
103
}
109
104
. onChange ( of: props. scrollEdgeAppearance) { newValue in
110
- updateTabBarAppearance ( props: props)
105
+ updateTabBarAppearance ( props: props, selectedActiveTintColor : selectedActiveTintColor )
111
106
}
112
107
. onChange ( of: props. translucent) { newValue in
113
- updateTabBarAppearance ( props: props)
108
+ updateTabBarAppearance ( props: props, selectedActiveTintColor: selectedActiveTintColor)
109
+ }
110
+ . onChange ( of: props. inactiveTintColor) { newValue in
111
+ updateTabBarAppearance ( props: props, selectedActiveTintColor: selectedActiveTintColor)
114
112
}
115
- . onAppear {
116
- // we have to keep onAppear to setup the appearance for the first render.
117
- let scrollEdgeAppearance = configureAppearance ( for: props. scrollEdgeAppearance ?? " " )
118
- let colorTintAppearance = configureAppearance ( appearance: scrollEdgeAppearance, inactiveTint: props. inactiveTintColor, activeTint: selectedActiveTintColor)
119
- setupTabBarAppearance ( colorTintAppearance)
113
+ . onChange ( of: selectedActiveTintColor) { newValue in
114
+ updateTabBarAppearance ( props: props, selectedActiveTintColor: selectedActiveTintColor)
120
115
}
121
116
}
122
117
}
123
118
124
119
private func configureAppearance( for appearanceType: String , appearance: UITabBarAppearance ) -> UITabBarAppearance {
125
-
126
120
switch appearanceType {
127
121
case " opaque " :
128
122
appearance. configureWithOpaqueBackground ( )
@@ -131,74 +125,68 @@ private func configureAppearance(for appearanceType: String, appearance: UITabBa
131
125
default :
132
126
appearance. configureWithDefaultBackground ( )
133
127
}
134
-
128
+
135
129
return appearance
136
130
}
137
131
138
- private func configureAppearance( appearance: UITabBarAppearance , inactiveTint inactiveTintColor: UIColor ? , activeTint activeTintColor: UIColor ? ) -> UITabBarAppearance {
132
+ private func setTabBarItemColors( _ itemAppearance: UITabBarItemAppearance , inactiveColor: UIColor ) {
133
+ itemAppearance. normal. iconColor = inactiveColor
134
+ itemAppearance. normal. titleTextAttributes = [ . foregroundColor: inactiveColor]
135
+ }
136
+
137
+
138
+ private func setTabBarItemColors( _ itemAppearance: UITabBarItemAppearance , activeColor: UIColor ) {
139
+ itemAppearance. selected. iconColor = activeColor
140
+ itemAppearance. selected. titleTextAttributes = [ . foregroundColor: activeColor]
141
+ }
142
+
143
+ private func configureAppearance( inactiveTint inactiveTintColor: UIColor ? , activeTint activeTintColor: UIColor ? , appearance: UITabBarAppearance ) -> UITabBarAppearance {
139
144
// @see https://stackoverflow.com/a/71934882
140
145
if let inactiveTintColor {
141
146
setTabBarItemColors ( appearance. stackedLayoutAppearance, inactiveColor: inactiveTintColor)
142
147
setTabBarItemColors ( appearance. inlineLayoutAppearance, inactiveColor: inactiveTintColor)
143
148
setTabBarItemColors ( appearance. compactInlineLayoutAppearance, inactiveColor: inactiveTintColor)
144
149
}
145
-
150
+
146
151
if let activeTintColor {
147
152
setTabBarItemColors ( appearance. stackedLayoutAppearance, activeColor: activeTintColor)
148
153
setTabBarItemColors ( appearance. inlineLayoutAppearance, activeColor: activeTintColor)
149
154
setTabBarItemColors ( appearance. compactInlineLayoutAppearance, activeColor: activeTintColor)
150
155
}
151
-
156
+
152
157
return appearance
153
158
}
154
159
155
- private func updateTabBarAppearance( props: TabViewProps ) {
160
+ private func updateTabBarAppearance( props: TabViewProps , selectedActiveTintColor: UIColor ? ) {
161
+ var appearance = UITabBarAppearance ( )
162
+ appearance = configureAppearance ( for: props. scrollEdgeAppearance ?? " " , appearance: appearance)
163
+ appearance = configureAppearance ( inactiveTint: props. inactiveTintColor, activeTint: selectedActiveTintColor, appearance: appearance)
164
+
156
165
if #available( iOS 15 . 0 , * ) {
157
- let appearance = UITabBarAppearance ( )
158
-
159
- UITabBar . appearance ( ) . scrollEdgeAppearance = configureAppearance ( for: props. scrollEdgeAppearance ?? " " , appearance: appearance)
160
-
166
+ UITabBar . appearance ( ) . scrollEdgeAppearance = appearance
167
+
161
168
if props. translucent == false {
162
169
appearance. configureWithOpaqueBackground ( )
163
170
}
164
-
171
+
165
172
if props. barTintColor != nil {
166
173
appearance. backgroundColor = props. barTintColor
167
174
}
168
-
169
- UITabBar . appearance ( ) . standardAppearance = appearance
170
175
} else {
171
176
UITabBar . appearance ( ) . barTintColor = props. barTintColor
172
177
UITabBar . appearance ( ) . isTranslucent = props. translucent
173
178
}
174
- }
175
-
176
- private func setupTabBarAppearance( _ appearance: UITabBarAppearance ) {
177
- if #available( iOS 15 . 0 , * ) {
178
- UITabBar . appearance ( ) . scrollEdgeAppearance = appearance
179
- }
180
- UITabBar . appearance ( ) . standardAppearance = appearance
181
- }
182
-
183
- private func setTabBarItemColors( _ itemAppearance: UITabBarItemAppearance , inactiveColor: UIColor ) {
184
- itemAppearance. normal. iconColor = inactiveColor
185
- itemAppearance. normal. titleTextAttributes = [ . foregroundColor: inactiveColor]
179
+
180
+ UITabBar . appearance ( ) . standardAppearance = appearance
186
181
}
187
182
188
183
189
- private func setTabBarItemColors( _ itemAppearance: UITabBarItemAppearance , activeColor: UIColor ) {
190
- itemAppearance. selected. iconColor = activeColor
191
- itemAppearance. selected. titleTextAttributes = [ . foregroundColor: activeColor]
192
- }
193
-
194
-
195
-
196
184
struct TabItem : View {
197
185
var title : String ?
198
186
var icon : UIImage ?
199
187
var sfSymbol : String ?
200
188
var labeled : Bool ?
201
-
189
+
202
190
var body : some View {
203
191
if let icon {
204
192
Image ( uiImage: icon)
@@ -226,7 +214,7 @@ extension View {
226
214
self
227
215
}
228
216
}
229
-
217
+
230
218
@ViewBuilder
231
219
func tabBadge( _ data: String ? ) -> some View {
232
220
if #available( iOS 15 . 0 , macOS 15 . 0 , visionOS 2 . 0 , * ) {
@@ -239,7 +227,7 @@ extension View {
239
227
self
240
228
}
241
229
}
242
-
230
+
243
231
@ViewBuilder
244
232
func ignoresTopSafeArea(
245
233
_ flag: Bool ,
@@ -254,10 +242,9 @@ extension View {
254
242
. ignoresSafeArea ( . container, edges: . horizontal)
255
243
. ignoresSafeArea ( . container, edges: . bottom)
256
244
. frame ( idealWidth: frame. width, idealHeight: frame. height)
257
- }
258
245
}
259
246
}
260
-
247
+
261
248
@ViewBuilder
262
249
func tintColor( _ color: UIColor ? ) -> some View {
263
250
if let color {
0 commit comments