SwiftUI - TabView disable background transparency
Thanks to @Asperi for pointing me in the correct direction. I found scrollEdgeAppearance
in UITabBarAppearance
.
@available(iOS 15.0, *)
@NSCopying open var scrollEdgeAppearance: UITabBarAppearance?
Describes the appearance attributes for the tabBar to use when an
observable scroll view is scrolled to the bottom. If not set,
standardAppearance will be used instead.
//@available(iOS 15.0, *)
//@NSCopying open var scrollEdgeAppearance: UITabBarAppearance?
let appearance: UITabBarAppearance = UITabBarAppearance()
init() {
UITabBar.appearance().scrollEdgeAppearance = appearance
}
Make TabView Background Transparent
The hosting view of every tab has system background color (which is opaque).
Here is possible workaround. Tested with Xcode 12 / iOS 14
struct BackgroundHelper: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
let view = UIView()
DispatchQueue.main.async {
// find first superview with color and make it transparent
var parent = view.superview
repeat {
if parent?.backgroundColor != nil {
parent?.backgroundColor = UIColor.clear
break
}
parent = parent?.superview
} while (parent != nil)
}
return view
}
func updateUIView(_ uiView: UIView, context: Context) {}
}
struct ContentView: View {
var body: some View {
ZStack {
Color.orange.edgesIgnoringSafeArea(.all)
// Sub-view inlined
TabView {
VStack {
Text("Hello World")
Button("Press Me", action: { print("Pressed") })
}
.background(BackgroundHelper()) // add to each tab if needed
.tabItem {
Text("First Page")
}
Text("Second")
.background(BackgroundHelper()) // add to each tab if needed
.tabItem {
Text("Second Page")
}
}
}
}
}
Making TabView not translucent on SwiftUI produces a new view on top
This is the correct way to do it.
It works with SwiftUI too as the TabView and NavigationView are actually UIHostedController for the legacy UITabBarController and UINavigationController.
Edit: Just watched Modernizing Your UI for iOS 13
This is the way to do it :
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.titleTextAttributes = [.foregroundColor: UIColor.white]
appearance.largeTitleTextAttributes = [.foregroundColor: UIColor .white]
Then set the appearance on the various type of appearance.
navigationBar.standardAppearance = appearance
navigationBar.compactAppearance = appearance
navigationBar.scrollEdgeAppearance = appearance
Reference: https://developer.apple.com/videos/play/wwdc2019/224/
2nd Edit: Need a figure out a clean way to get to the UINavigationController from a SwiftUI view.
In the meantime, this will help:
extension UINavigationController {
override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
navigationBar.standardAppearance = appearance
navigationBar.compactAppearance = appearance
navigationBar.scrollEdgeAppearance = appearance
}
}
extension UITabBarController {
override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let appearance = UITabBarAppearance()
appearance.configureWithOpaqueBackground()
tabBar.standardAppearance = appearance
}
}
SwiftUI transparent TabView (without background blur)?
Use UIBarAppearance.configureWithTransparentBackground()
.
struct ContentView: View {
init() {
let transparentAppearence = UITabBarAppearance()
transparentAppearence.configureWithTransparentBackground() //
UITabBar.appearance().standardAppearance = transparentAppearence
}
var body: some View {
TabView {
List {
ForEach(1...40, id: \.self) { eachRowIndex in
Text("Row \(eachRowIndex)")
}
}
.listStyle(.plain)
.tabItem {
Image(systemName: "house.fill")
Text("Home")
}
}
}
}
SwiftUI TabView clear background after Xcode upgrade 12.4 - 13.2 with Mapbox/UIKIT?
iOS 15 changed the default look of the TabBar when there is nothing underneath it to scroll.
What worked for me (to change it back to the iOS 14 default) is modifying the TabBar in an onAppear
statement:
TabView {
...
}
.onAppear {
let tabBarAppearance = UITabBarAppearance()
tabBarAppearance.configureWithDefaultBackground()
UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance
}
How can i create a transparent background in react navigation 5.x?
Somewhere else in your code, you have a component that uses your DashboardTabBar component. You should add a tabBarOptions prop with a style object to the Tab.Navigator component, like so:
<Tab.Navigator
tabBar={...}
tabBarOptions={{
style: {
backgroundColor: 'transparent',
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
elevation: 0, <----to get rid of a shadow problem on Android
},
}}>
{ /* ...your screens go here */ }
</Tab.Navigator>
I have successfully done this on both iOS and Android. Personally, it doesn't look good for my app.
iOS 15 tab bar transparent after scrolling to the bottom
With iOS 15, Apple adds the scrollEdgeAppearance
property for configuring the appearance of the tab bar while edge scrolling.
https://developer.apple.com/documentation/uikit/uitabbar/3750912-scrolledgeappearance?changes=latest_minor
To fix the transparent tab bar, you should create a custom scroll edge appearance and set it to the tab bar.
if #available(iOS 15.0, *) {
let appearance = UITabBarAppearance()
appearance.backgroundEffect = UIBlurEffect(style: .light)
tabBar.scrollEdgeAppearance = appearance
}
Result:
Related Topics
Parametrized Unit Tests in Swift
Xcode Error: Ar Reference Image Must Have Non Zero Positive Width
iOS 16 Swiftui List Background
Which Optimization Level Should I Choose for Release
Filtering Realm Objects with Swift
How to Add a Menu to The Application in The Dock
How to Get Reliable Timing for My Audio App
Using Dateformatter with Timezone to Format Dates in Swift
How to Check If Optional Is Not Nil and Property Is True in One Expression
Swift Unable to Locate and Read Property List (.Plist) File
How to Refresh The Google Map in My Application Using Swift
Xcode Issue: Library Not Loaded: @Rpath/Libswiftappkit.Dylib
Get Applicationdidfinishlaunching Call in a View Controller. Parse Not Initialized Yet
Converting Cmtime to String Is Wrong Value Return