I am having a rather strange issue trying to create a custom navigation bar for an iPad app that I am developing. The model in which I generate the options for the navigation bar is called HomeViewModel and here is how it looks like:
import Foundation
import SwiftUI
enum HomeTabs {
case Restaurants
case Minibar
case Spa
case Recreation
case KidsClub
case DiveCenter
case ResortMap
case More
}
struct HomeNavTabInfo: Identifiable {
var id = UUID()
var view: HomeTabs
var icon: String
var selectedIcon: String
var name: String
}
class HomeViewModel: ObservableObject {
@Published var HomeNavTabs = [HomeNavTabInfo]()
@Published var selectedTab = HomeTabs.Restaurants
@Published var vakkaruGray = Color(.sRGB, red: 191/255, green: 184/255, blue: 175/255, opacity: 1)
init(){
self.HomeNavTabs.append(HomeNavTabInfo(view: .Restaurants, icon: "icon_rest", selectedIcon: "icon_restp", name: "Restaurant"))
self.HomeNavTabs.append(HomeNavTabInfo(view: .Minibar, icon: "icon_minib", selectedIcon: "icon_minibp", name: "Minibar"))
self.HomeNavTabs.append(HomeNavTabInfo(view: .Spa, icon: "icon_spa", selectedIcon: "icon_spap", name: "Spa"))
self.HomeNavTabs.append(HomeNavTabInfo(view: .Recreation, icon: "icon_rec", selectedIcon: "icon_recp", name: "Recreation"))
self.HomeNavTabs.append(HomeNavTabInfo(view: .KidsClub, icon: "icon_kid", selectedIcon: "icon_kidp", name: "KidsClub"))
self.HomeNavTabs.append(HomeNavTabInfo(view: .DiveCenter, icon: "icon_dive", selectedIcon: "icon_divep", name: "DiveCenter"))
self.HomeNavTabs.append(HomeNavTabInfo(view: .ResortMap, icon: "icon_map", selectedIcon: "icon_mapp", name: "ResortMap"))
self.HomeNavTabs.append(HomeNavTabInfo(view: .More, icon: "icon_more", selectedIcon: "icon_morep", name: "More"))
}
}
At a later stage I do plan to use an external API to fetch the options that I am adding manually over here within init, perhaps stating that would give more sense why I am generating the options for the nav bar in this manner.
Now lets look at the views. To keep things clean I have 3 views aiding each other for the view that has this navigation bar - which is HomeView, HomeContent and HomeMainNavBar.
HomeView:
import SwiftUI
struct HomeView: View {
var body: some View {
NavigationView{
ZStack {
// MARK: bacground Image
Image("background")
.resizable()
.scaledToFill()
.ignoresSafeArea()
// MARK: Main Content
HomeContent()
}
}
.navigationViewStyle(.stack)
}
}
HomeContent:
import SwiftUI
struct HomeContent: View {
@EnvironmentObject var HomeModel: HomeViewModel
var body: some View {
GeometryReader { proxy in
VStack {
// MARK: LOGO
Image("logo white")
.padding(.vertical, 30)
Spacer()
// MARK: Navigation - Header
Text("OUR DINNING & EXPERIENCES")
.font(Font.custom("Lato-Bold", size:30))
.foregroundColor(.white)
// MARK: Navigation - Bar
HomeMainNavBar(navBarWidth: proxy.size.width * 80/100)
// MARK: Footer
Text("For assistance contact your butler or our guest service center via 0")
.font(Font.custom("Lato-BoldItalic", size: 18))
.foregroundColor(.white)
.padding(.vertical, 20)
}
.frame(width: proxy.size.width)
}
}
}
HomeMainNavBar:
import SwiftUI
struct HomeMainNavBar: View {
@EnvironmentObject var HomeModel: HomeViewModel
var navBarWidth: CGFloat
var body: some View {
VStack {
Rectangle()
.fill(HomeModel.vakkaruGray)
.frame(height: 5)
// MARK: Navigation - Buttons
HStack{
ForEach (HomeModel.HomeNavTabs) { tab in
NavigationLink {
SecondScreenView()
} label: {
Image(HomeModel.selectedTab == tab.view ? tab.selectedIcon : tab.icon)
.resizable()
.scaledToFit()
.frame(height: 125)
.onTapGesture {
HomeModel.selectedTab = tab.view
}
}
}
NavigationLink {
SecondScreenView()
} label: {
Image("icon_rest")
.resizable()
.scaledToFit()
.frame(height: 125)
}
}
Spacer()
Rectangle()
.fill(HomeModel.vakkaruGray)
.frame(height: 5)
}
.frame(width: navBarWidth,height: 150)
}
}
Here as you could see I am using a ForEach loop to create the options/Navigation Links within the Horizontal Stack. When these links are pressed it does not navigate to the SecondScreenView() - here SecondScreenView is just a basic screen with a Text element on it, nothing fancy. However I also noticed that if I create a NavigationLink out of the ForEach loop, this particular navigation link which is out of the ForEach loop works and when once pressed it navigates to SecondScreenView just as expected.
I am not sure where and what I am doing wrong and how to fix it, any assistance will be much appreciated. As mentioned earlier I do require to generate these options programatically according to the response from the API i.e. I need to be able to loop through the HomeNavTabInfo to create the Navigation Links.
Looking forward to a quick and favorable response.