One of my tabs shows a list of items. I wish to add a gradient above the tab view to show that there are more items in the list and user can scroll. Please refer to attached screenshot. I am hiding the scroll indicator.
The way I am trying to achieve this is by finding the height of the tab bar and adding that as the bottom padding for the gradient. I found another post on SO which helped me getting the accurate height of the tab view. However even with that, the gradient isn't getting placed at the right location.
How can I move the gradient to the position highlighted in purple in the attached screenshot?
Code:
import SwiftUI
import Foundation
struct ContentView: View {
@State var activeTab = 1
@State var tabBarHeight: CGFloat = 0.0
var body: some View {
TabView(selection: $activeTab) {
Group {
Text("profile")
.tabItem {
Label("profile", systemImage: "square.text.square.fill")
}
.tag(0)
Text("search")
.tabItem {
Label("search", systemImage: "magnifyingglass")
}
.background(TabBarAccessor { tabBar in
tabBarHeight = tabBar.bounds.height
})
.tag(1)
}
}
.background(Color(red: 0.98, green: 0.98, blue: 0.98).opacity(0.94))
.onAppear {
let appearance = UITabBarAppearance()
UITabBar.appearance().scrollEdgeAppearance = appearance
}
.overlay {
LinearGradient(gradient:
Gradient(
colors: [Color.gray.opacity(0.6), Color.gray.opacity(0)]),
startPoint: .top, endPoint: .bottom
)
// .frame(height: 20.0).offset(y:tabBarHeight)
.frame(height: 20.0).padding(.bottom, -tabBarHeight)
}
}
}
// Helper bridge to UIViewController to access enclosing UITabBarController
// and thus its UITabBar
// Found from - https://stackoverflow.com/a/59972635/697033
struct TabBarAccessor: UIViewControllerRepresentable {
var callback: (UITabBar) -> Void
private let proxyController = ViewController()
func makeUIViewController(context: UIViewControllerRepresentableContext<TabBarAccessor>) ->
UIViewController {
proxyController.callback = callback
return proxyController
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<TabBarAccessor>) {
}
typealias UIViewControllerType = UIViewController
private class ViewController: UIViewController {
var callback: (UITabBar) -> Void = { _ in }
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let tabBar = self.tabBarController {
self.callback(tabBar.tabBar)
}
}
}
}
Screenshot: