Home > Net >  How to pass a Buttonbar to Views
How to pass a Buttonbar to Views

Time:08-25

I got a NavigationBar at the Bottom of some of my Views, but not all of them. It looks like this:

enter image description here

And I need it to refresh in every View once I change to another View since I want to implement changing the Button colors to represent which View is active at the moment. So if the current View is Home I want it to look like this:

enter image description here

This is the code for the buttonbar:

struct ButtonBar: View {
    @State var selection: Int? = nil
    
    var body: some View {
            HStack {
                NavigationLink(destination: ShopView(), tag: 1, selection: $selection) {
                    Button() {
                        self.selection = 1
                    } label: {
                        Image("shoppingCart").resizable()
                            .renderingMode(.template)
                            .foregroundColor(selection == 1 ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
                            .frame(width: 34, height: 34)
                    }
                }
                Spacer()
                NavigationLink(destination: HomeView(), tag: 2, selection: $selection) {
                    Button() {
                        self.selection = 2
                    } label: {
                        Image("home").resizable()
                            .renderingMode(.template)
                            .foregroundColor(selection == 2 ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
                            .frame(width: 34, height: 34)
                    }
                }
                Spacer()
                NavigationLink(destination: MessagesView(), tag: 3, selection: $selection) {
                    Button() {
                        self.selection = 3
                    } label: {
                        Image("message").resizable()
                            .renderingMode(.template)
                            .foregroundColor(Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
                            .frame(width: 24, height: 24)
                    }
                }
                Spacer()
                NavigationLink(destination: EventsView(), tag: 4, selection: $selection) {
                Button() {
                    self.selection = 4
                } label: {
                    Image("calender").resizable()
                        .renderingMode(.template)
                        .foregroundColor(Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
                        .frame(width: 34, height: 34)
                    }
                }
                Spacer()
                NavigationLink(destination: SettingsView(), tag: 5, selection: $selection) {
                Button() {
                    self.selection = 5
                } label: {
                    Image("personCover").resizable()
                        .renderingMode(.template)
                        .foregroundColor(Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
                        .frame(width: 36, height: 36)
                    }
                }
            }.padding(.init(top: 0, leading: 8, bottom: 8, trailing: 8))
    }
}

When I render this View in my Views like this ButtonBar() it does not refresh colors since it is created as a new View in every View. Is there a way to pass a View as an environmentObject just like with States?

CodePudding user response:

Using TabView would work perfectly if I didn't need custom buttons, but this code worked for me:

import Foundation

class ViewRouter: ObservableObject {
    @Published var currentPage: Page = .home
}
enum Page {
     case home
     case shop
     case messages
     case events
     case settings
}
struct ContentView: View {
    @StateObject var viewRouter = ViewRouter()
    var body: some View {
        VStack {
                ZStack {
                    switch viewRouter.currentPage {
                    case .shop:
                        ShopView().environmentObject(loginViewController)
                    case .home:
                        HomeView()
                    case .messages:
                        MessagesView()
                    case .events:
                        EventsView()
                    case .settings:
                        SettingsView()
                    }
                }
                HStack {
                        Button() {
                            viewRouter.currentPage = .shop
                        } label: {
                            Image("shoppingCart").resizable()
                                .renderingMode(.template)
                                .foregroundColor(viewRouter.currentPage == .shop ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
                                .frame(width: 34, height: 34)
                        }
                    Spacer()
                        Button() {
                            viewRouter.currentPage = .home
                        } label: {
                            Image("home").resizable()
                                .renderingMode(.template)
                                .foregroundColor(viewRouter.currentPage == .home ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
                                .frame(width: 34, height: 34)
                        }
                    Spacer()
                        Button() {
                            viewRouter.currentPage = .messages
                        } label: {
                            Image("message").resizable()
                                .renderingMode(.template)
                                .foregroundColor(viewRouter.currentPage == .messages ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
                                .frame(width: 24, height: 24)
                        }
                    Spacer()
                    Button() {
                        viewRouter.currentPage = .events
                    } label: {
                        Image("calender").resizable()
                            .renderingMode(.template)
                            .foregroundColor(viewRouter.currentPage == .events ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
                            .frame(width: 34, height: 34)
                        }
                    Spacer()
                    Button() {
                        viewRouter.currentPage = .settings
                    } label: {
                        Image("personCover").resizable()
                            .renderingMode(.template)
                            .foregroundColor(viewRouter.currentPage == .settings ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
                            .frame(width: 36, height: 36)
                        }
                }.padding(.init(top: 0, leading: 8, bottom: 8, trailing: 8))
            }
        }
    }
}

CodePudding user response:

Create your TabView in ContentView. There'll be three tab items: one that will lead the user to HomeView, one that will lead the user to ShopView, and another one to MessageView.Make sure to have a Navigation Link in your parent View that will lead to a child View. For example, in the code below:

import SwiftUI

struct ContentView: View {
    
    @State private var selection = 0
    
    var body: some View {
        NavigationView {
            TabView(selection: $selection){
                NavigationLink(destination: HomeView()){
                    Text("Home Tab")
                        .font(.system(size: 30, weight: .bold, design: .rounded))
                }
                .tabItem {
                    Image(systemName: "house.fill")
                    Text("Home")
                }
                .tag(0)
                
                NavigationLink(destination: ShopView()){
                    Text("Shop Tab")
                        .font(.system(size: 30, weight: .bold, design: .rounded))
                }
                .tabItem {
                    Image(systemName: "bookmark.circle.fill")
                    Text("Shop")
                }
                .tag(1)
                
                NavigationLink(destination: MessageView()){
                    Text("Message Tab")
                        .font(.system(size: 30, weight: .bold, design: .rounded))
                }
                .tabItem {
                    Image(systemName: "message.fill")
                    Text("Message")
                }
                .tag(2)
            }
            .accentColor(.yellow)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Output :

enter image description here

  • Related