11import Foundation
22import SwiftUI
33import React
4+ @_spi ( Advanced) import SwiftUIIntrospect
5+
46
57/**
68 Props that component accepts. SwiftUI view gets re-rendered when ObservableObject changes.
@@ -52,6 +54,8 @@ struct TabViewImpl: View {
5254 @ObservedObject var props : TabViewProps
5355 var onSelect : ( _ key: String ) -> Void
5456 var onLongPress : ( _ key: String ) -> Void
57+ @Weak var tabBar : UITabBar ?
58+
5559
5660 var body : some View {
5761 TabView ( selection: $props. selectedPage) {
@@ -72,9 +76,15 @@ struct TabViewImpl: View {
7276 emitHapticFeedback ( )
7377 }
7478 } )
79+ . introspectTabView ( closure: { tabController in
80+ tabBar = tabController. tabBar
81+ } )
82+ . onChange ( of: tabBar) { newValue in
83+ updateTabBarAppearance ( props: props, tabBar: tabBar)
84+ }
85+ . configureAppearance ( props: props, tabBar: tabBar)
7586 . tintColor ( props. selectedActiveTintColor)
7687 . getSidebarAdaptable ( enabled: props. sidebarAdaptable ?? false )
77- . configureAppearance ( props: props)
7888 . onChange ( of: props. selectedPage ?? " " ) { newValue in
7989 if ( props. disablePageAnimations) {
8090 UIView . setAnimationsEnabled ( false )
@@ -136,66 +146,6 @@ struct TabViewImpl: View {
136146 }
137147}
138148
139- @available ( iOS 15 . 0 , * )
140- private func configureAppearance( for appearanceType: String , appearance: UITabBarAppearance ) -> UITabBarAppearance {
141- if ( appearanceType == " transparent " ) {
142- return appearance
143- }
144-
145- switch appearanceType {
146- case " opaque " :
147- appearance. configureWithOpaqueBackground ( )
148- default :
149- appearance. configureWithDefaultBackground ( )
150- }
151-
152- UITabBar . appearance ( ) . scrollEdgeAppearance = appearance
153-
154- return appearance
155- }
156-
157- private func setTabBarItemColors( _ itemAppearance: UITabBarItemAppearance , inactiveColor: UIColor ) {
158- itemAppearance. normal. iconColor = inactiveColor
159- itemAppearance. normal. titleTextAttributes = [ . foregroundColor: inactiveColor]
160- }
161-
162- private func configureAppearance( inactiveTint inactiveTintColor: UIColor ? , appearance: UITabBarAppearance ) -> UITabBarAppearance {
163- // @see https://stackoverflow.com/a/71934882
164- if let inactiveTintColor {
165- setTabBarItemColors ( appearance. stackedLayoutAppearance, inactiveColor: inactiveTintColor)
166- setTabBarItemColors ( appearance. inlineLayoutAppearance, inactiveColor: inactiveTintColor)
167- setTabBarItemColors ( appearance. compactInlineLayoutAppearance, inactiveColor: inactiveTintColor)
168- }
169-
170- return appearance
171- }
172-
173- private func updateTabBarAppearance( props: TabViewProps ) {
174- var appearance = UITabBarAppearance ( )
175- appearance = configureAppearance (
176- inactiveTint: props. inactiveTintColor,
177- appearance: appearance
178- )
179-
180-
181- if #available( iOS 15 . 0 , * ) {
182- appearance = configureAppearance ( for: props. scrollEdgeAppearance ?? " " , appearance: appearance)
183-
184- if props. translucent == false {
185- appearance. configureWithOpaqueBackground ( )
186- }
187-
188- if props. barTintColor != nil {
189- appearance. backgroundColor = props. barTintColor
190- }
191- } else {
192- UITabBar . appearance ( ) . barTintColor = props. barTintColor
193- UITabBar . appearance ( ) . isTranslucent = props. translucent
194- }
195-
196- UITabBar . appearance ( ) . standardAppearance = appearance
197- }
198-
199149struct TabItem : View {
200150 var title : String ?
201151 var icon : UIImage ?
@@ -215,6 +165,43 @@ struct TabItem: View {
215165 }
216166}
217167
168+ private func updateTabBarAppearance( props: TabViewProps , tabBar: UITabBar ? ) {
169+ guard let tabBar else { return }
170+ let appearanceType = props. scrollEdgeAppearance
171+
172+ if ( appearanceType == " transparent " ) {
173+ tabBar. barTintColor = props. barTintColor
174+ tabBar. isTranslucent = props. translucent
175+ tabBar. unselectedItemTintColor = props. inactiveTintColor
176+ return
177+ }
178+
179+ let appearance = UITabBarAppearance ( )
180+
181+ switch appearanceType {
182+ case " opaque " :
183+ appearance. configureWithOpaqueBackground ( )
184+ default :
185+ appearance. configureWithDefaultBackground ( )
186+ }
187+ appearance. backgroundColor = props. barTintColor
188+
189+ if let inactiveTintColor = props. inactiveTintColor {
190+ let itemAppearance = UITabBarItemAppearance ( )
191+ itemAppearance. normal. iconColor = inactiveTintColor
192+ itemAppearance. normal. titleTextAttributes = [ . foregroundColor: inactiveTintColor]
193+
194+ appearance. stackedLayoutAppearance = itemAppearance
195+ appearance. inlineLayoutAppearance = itemAppearance
196+ appearance. compactInlineLayoutAppearance = itemAppearance
197+ }
198+
199+ tabBar. standardAppearance = appearance
200+ if #available( iOS 15 . 0 , * ) {
201+ tabBar. scrollEdgeAppearance = appearance. copy ( )
202+ }
203+ }
204+
218205extension View {
219206 @ViewBuilder
220207 func getSidebarAdaptable( enabled: Bool ) -> some View {
@@ -268,25 +255,22 @@ extension View {
268255 }
269256
270257 @ViewBuilder
271- func configureAppearance( props: TabViewProps ) -> some View {
258+ func configureAppearance( props: TabViewProps , tabBar : UITabBar ? ) -> some View {
272259 self
273- . onAppear ( ) {
274- updateTabBarAppearance ( props: props)
275- }
276260 . onChange ( of: props. barTintColor) { newValue in
277- updateTabBarAppearance ( props: props)
261+ updateTabBarAppearance ( props: props, tabBar : tabBar )
278262 }
279263 . onChange ( of: props. scrollEdgeAppearance) { newValue in
280- updateTabBarAppearance ( props: props)
264+ updateTabBarAppearance ( props: props, tabBar : tabBar )
281265 }
282266 . onChange ( of: props. translucent) { newValue in
283- updateTabBarAppearance ( props: props)
267+ updateTabBarAppearance ( props: props, tabBar : tabBar )
284268 }
285269 . onChange ( of: props. inactiveTintColor) { newValue in
286- updateTabBarAppearance ( props: props)
270+ updateTabBarAppearance ( props: props, tabBar : tabBar )
287271 }
288272 . onChange ( of: props. selectedActiveTintColor) { newValue in
289- updateTabBarAppearance ( props: props)
273+ updateTabBarAppearance ( props: props, tabBar : tabBar )
290274 }
291275 }
292276
0 commit comments