I have a SwiftUI app that will have a floating podcast player, similar to the Apple Music player that sits just above the Tab Bar and persists across all tabs and views whil
It seems, that you need to know the maximal size of player (size of space above tab bar), not height of tab bar self.
Using GeometryReader and PreferenceKey are the handy tool for that
import Combine
struct Size: PreferenceKey {
typealias Value = [CGRect]
static var defaultValue: [CGRect] = []
static func reduce(value: inout [CGRect], nextValue: () -> [CGRect]) {
value.append(contentsOf: nextValue())
}
}
struct HomeView: View {
let txt: String
var body: some View {
GeometryReader { proxy in
Text(self.txt).preference(key: Size.self, value: [proxy.frame(in: CoordinateSpace.global)])
}
}
}
struct ContentView: View {
@State var playerFrame = CGRect.zero
var body: some View {
TabView {
HomeView(txt: "Hello").tabItem {
Image(systemName: "house")
Text("A")
}.border(Color.green).tag(1)
HomeView(txt: "World!").tabItem {
Image(systemName: "house")
Text("B")
}.border(Color.red).tag(2)
HomeView(txt: "Bla bla").tabItem {
Image(systemName: "house")
Text("C")
}.border(Color.blue).tag(3)
}
.onPreferenceChange(Size.self, perform: { (v) in
self.playerFrame = v.last ?? .zero
print(self.playerFrame)
})
.overlay(
Color.yellow.opacity(0.2)
.frame(width: playerFrame.width, height: playerFrame.height)
.position(x: playerFrame.width / 2, y: playerFrame.height / 2)
)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
In the example I reduce the size with .padding() on yellow transparent rectangle, to be sure no part could be hidden (out of screen)
Even the height of tab bar could be calculated, if necessary, but I am not able to imagine for what.