앱을 사용하다보면 우리는 다양한 Tab bar를 보게된다.
SwiftUI에서는 TabView를 통해 쉽게 구현할 수 있다.
//TabView
struct ContentView : View {
var body: some View {
TabView {
Text("The First Tab")
.tabItem {
Image(systemName: "1.square.fill")
}
Text("The Second Tab")
.tabItem {
Image(systemName: "2.square.fill")
}
Text("The Third Tab")
.tabItem {
Image(systemName: "3.square.fill")
}
}
}
}
하지만 내가 만들고자 하는 Tab Bar를 구현하기 위해서는 많은 수정이 불가피했다.
다음 동영상을 참고하여 Custom Tab Bar를 구현해보았다.
//Custom TabView
enum Tab {
case first
case second
case third
}
struct ContentView : View {
@State var selectedTab: Tab = .first
var body: some View {
VStack {
Spacer()
switch selectedTab {
case .first:
Text("The First Tab")
case .second:
Text("The Second Tab")
case .third:
Text("The Third Tab")
}
Spacer()
CustomTabView(selectedTab: $selectedTab)
}
}
}
struct CustomTabView: View {
@Binding var selectedTab: Tab
var body: some View {
HStack {
Spacer()
Button() {
selectedTab = .first
} label: {
Image(systemName: "1.square.fill")
}
Spacer()
Button {
selectedTab = .second
} label: {
Image(systemName: "2.square.fill")
}
Spacer()
Button {
selectedTab = .third
} label: {
Image(systemName: "3.square.fill")
}
Spacer()
}
}
}
ZStack을 사용해 동그란 버튼을 만들고 offset으로 위치를 변경하였다.
struct CustomTabView: View {
@Binding var selectedTab: Tab
var body: some View {
HStack {
Spacer()
Button() {
selectedTab = .first
} label: {
Image(systemName: "1.square")
}
Spacer()
ZStack {
Circle()
.foregroundColor(Color(.orange))
.frame(width: 90, height: 90)
Button {
selectedTab = .second
} label: {
Image(systemName: "2.square")
}
}
.offset(y: -32)
Spacer()
Button {
selectedTab = .third
} label: {
Image(systemName: "3.square")
}
Spacer()
}
}
}
Tab Bar의 배경은 도형을 그리는 것이 익숙치 않아 이미지로 넣어주었고 색상은 Assets에 "Symbol"로 지정하여 사용하였다.
몇가지를 추가로 수정한 코드와 결과는 다음과 같다.
struct CustomTabView: View {
@Binding var selectedTab: Tab
var body: some View {
ZStack {
Image("background")
.resizable()
.aspectRatio(contentMode: .fill)
.offset(y: 15)
HStack {
Spacer()
Button {
selectedTab = .home
} label: {
Image(systemName: selectedTab == .home ? "house.fill" : "house")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 30)
.foregroundColor(.white)
}
Spacer()
Button {
selectedTab = .shop
} label: {
ZStack {
Circle()
.foregroundColor(Color("Symbol"))
.frame(width: 90, height: 90)
Image(systemName: selectedTab == .shop ? "basket.fill" : "basket")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40)
.foregroundColor(.white)
}
.offset(y: -32)
}
Spacer()
Button {
selectedTab = .profile
} label: {
Image(systemName: selectedTab == .profile ? "person.fill" : "person")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 30)
.foregroundColor(.white)
}
Spacer()
}
}
.frame(height: 50)
}
}