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()
}