Hi I am a beginner and I am preparing to make a Tabbar component for use in my practice APP. The component uses Image as the button. When the button is clicked (onTapGesture), I hope that the color in the IMAGE will change, but now When running to onTapGesture, XCode crashes, who knows how to write this code to make it run normally. Thanks
class MainViewManager : ObservableObject{
@Published var tabbarStatus : TabbarStatus = .homeView
enum TabbarStatus : CaseIterable {
case homeView
case articsPage
case profile
var icon : String{
switch self{
case .homeView:
return "house"
case .articsPage:
return "person.2"
case .profile:
return "person.crop.circle"
}
}
}
}
struct MainTabbar: View {
@EnvironmentObject var vm : MainViewManager
@State var btnColor : Color = .gray
var body: some View {
HStack{
ForEach(MainViewManager.TabbarStatus.allCases, id: \.self) { tabbarItem in
//let selected = tabbarItem == vm.tabbarStatus
Image(systemName:tabbarItem.icon)
.foregroundStyle(btnColor)
.onTapGesture {
vm.tabbarStatus = tabbarItem
btnColor = Color.accentColor
}
if tabbarItem != .profile {
Spacer()
}
}
}
.padding(.horizontal,30)
.padding(.all)
.frame(maxHeight: .infinity ,alignment: .bottom)
.background(Color.white)
}
}
#Preview {
MainTabbar()
}
I've added a selected
tab bar item as a @State
var. Such vars should be private
because they should only be modified within their own View.
Also, you only really need to change the selection within the .onTapGesture
because the view will take its data from the change you made, i.e. the image color is set by the value of selected
.
class MainViewManager: ObservableObject{
@Published var tabbarStatus: TabbarStatus = .homeView
enum TabbarStatus: CaseIterable {
case homeView
case articsPage
case profile
var icon: String {
switch self {
case .homeView:
return "house"
case .articsPage:
return "person.2"
case .profile:
return "person.crop.circle"
}
}
}
}
struct MainTabbar: View {
@EnvironmentObject var vm: MainViewManager
@State private var selected: MainViewManager.TabbarStatus = .homeView
var body: some View {
HStack {
ForEach(MainViewManager.TabbarStatus.allCases, id: \.self) { tabbarItem in
Image(systemName: tabbarItem.icon)
.foregroundStyle(tabbarItem == selected ? Color.accentColor : .gray)
.onTapGesture {
selected = tabbarItem
}
if(tabbarItem != .profile) {
Spacer()
}
}
}
.padding(.horizontal, 30)
.padding(.all)
.frame(maxHeight: .infinity, alignment: .bottom)
.background(Color.white)
}
}
#Preview {
MainTabbar()
}