I created a tabBar including 2 tabs. It has a horizontal scrollBar which includes a HStack view. But the HStack view only takes a part of screen width as screenshot in below. I used .frame(maxWidth: .infinity)
, however it changed nothing.
What I want is to make HStack view takes all the screen width size. Please see the 2nd screenshot in below.
struct ContentView: View {
@State private var currentTab: Int = 0
var body: some View {
ZStack(alignment: .top) {
TabView(selection: $currentTab) {
TextClipView().tag(0)
BookView().tag(1)
}
.tabViewStyle(.page(indexDisplayMode: .never))
.ignoresSafeArea(.all)
TabBarView(currentTab: $currentTab)
}
}
}
struct TabBarView: View {
@Binding var currentTab: Int
@Namespace var namespace
var tabBarOptions: [String] = ["text.bubble", "book"]
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 20) {
ForEach(Array(zip(tabBarOptions.indices, tabBarOptions)),
id: \.0,
content: {
index, name in
TabBarItem(currentTab: $currentTab,
namespace: namespace,
tabBarItemName: name,
tab: index)
})
}
.padding(.horizontal)
.frame(maxWidth: .infinity)
.border(.red, width: 4)
}
.frame(height: 80)
.border(.green, width: 2)
.ignoresSafeArea(.all)
}
}
struct TabBarItem: View {
@Binding var currentTab: Int
let namespace: Namespace.ID
var tabBarItemName: String
var tab: Int
var body: some View {
Button {
currentTab = tab
} label: {
VStack {
Spacer()
Image(systemName: tabBarItemName)
.font(.title)
if currentTab == tab {
Color.black
.frame(height: 2)
.matchedGeometryEffect(id: "underline",
in: namespace,
properties: .frame)
} else {
Color.clear.frame(height: 2)
}
}
.animation(.spring(), value: currentTab)
}
.buttonStyle(.plain)
}
}
#Preview {
ContentView()
}
Presumably, you are using a ScrollView
because there might be times when the width of the content exceeds the available width.
To make the content fill the Scrollview
when its ideal width is smaller, you can use a GeometryReader
to measure the width and then set this as minWidth
on the HStack
.
Like this:
// TabBarView
var body: some View {
GeometryReader { proxy in
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 20) {
// content as before
}
.padding(.horizontal)
.frame(minWidth: proxy.size.width)
.border(.red, width: 4)
}
}
.frame(height: 80)
.border(.green, width: 2)
.ignoresSafeArea(.all)
}