Open twodayslate opened 1 year ago
Hello, @twodayslate!
I will look into this issue on my free time
Thanks :)
Since the TabBar can also be floating, by default, content can fall behind it. If you don't want that behaviour, add a bottom padding of the height of your TabBar.
@onl1ner maybe it would be a nice feature to be able to specify it as not floating and automatically modify the content's area.
My solution was based on ChildSizeReader
I found somewhere on SO + modified TabView
+
added .edgesIgnoringSafeArea([.bottom, .leading, .trailing])
to support landscape device orientation
struct ChildSizeReader<Content: View>: View {
@Binding var size: CGSize
let content: () -> Content
var body: some View {
ZStack {
content()
.background(
GeometryReader { proxy in
Color.clear
.preference(key: SizePreferenceKey.self, value: proxy.size)
}
)
}
.onPreferenceChange(SizePreferenceKey.self) { preferences in
self.size = preferences
}
}
}
struct SizePreferenceKey: PreferenceKey {
typealias Value = CGSize
static var defaultValue: Value = .zero
static func reduce(value _: inout Value, nextValue: () -> Value) {
_ = nextValue()
}
}
public struct TabBar<TabItem: Tabbable, Content: View>: View {
...
@State var barSize: CGSize = .zero
public var body: some View {
return ZStack {
self.content
.frame(maxWidth: .infinity, maxHeight: .infinity)
.environmentObject(self.selectedItem).edgesIgnoringSafeArea(.bottom)
.padding(.bottom, barSize.height)
.edgesIgnoringSafeArea(.bottom)
GeometryReader { geometry in
VStack {
Spacer()
ChildSizeReader(size: $barSize) {
self.tabBarStyle.tabBar(with: geometry) {
.init(self.tabItems)
}
}
}
.edgesIgnoringSafeArea([.bottom, .leading, .trailing])
.visibility(self.visibility)
}
}
.onPreferenceChange(TabBarPreferenceKey.self) { value in
self.items = value
}
}
}
'safeAreaInset(edge:alignment:spacing:content:)' should work but it is only available in > iOS 15.0
My solution was based on
ChildSizeReader
I found somewhere on SO + modifiedTabView
+
added.edgesIgnoringSafeArea([.bottom, .leading, .trailing])
to support landscape device orientationstruct ChildSizeReader<Content: View>: View { @Binding var size: CGSize let content: () -> Content var body: some View { ZStack { content() .background( GeometryReader { proxy in Color.clear .preference(key: SizePreferenceKey.self, value: proxy.size) } ) } .onPreferenceChange(SizePreferenceKey.self) { preferences in self.size = preferences } } } struct SizePreferenceKey: PreferenceKey { typealias Value = CGSize static var defaultValue: Value = .zero static func reduce(value _: inout Value, nextValue: () -> Value) { _ = nextValue() } } public struct TabBar<TabItem: Tabbable, Content: View>: View { ... @State var barSize: CGSize = .zero public var body: some View { return ZStack { self.content .frame(maxWidth: .infinity, maxHeight: .infinity) .environmentObject(self.selectedItem).edgesIgnoringSafeArea(.bottom) .padding(.bottom, barSize.height) .edgesIgnoringSafeArea(.bottom) GeometryReader { geometry in VStack { Spacer() ChildSizeReader(size: $barSize) { self.tabBarStyle.tabBar(with: geometry) { .init(self.tabItems) } } } .edgesIgnoringSafeArea([.bottom, .leading, .trailing]) .visibility(self.visibility) } } .onPreferenceChange(TabBarPreferenceKey.self) { value in self.items = value } } }
Saved my life. 👍🏻