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
ScrollViewbecause there might be times when the width of the content exceeds the available width.To make the content fill the
Scrollviewwhen its ideal width is smaller, you can use aGeometryReaderto measure the width and then set this asminWidthon theHStack.Like this: