Home > Software design >  SwiftUI - TabView init after click on TabItem
SwiftUI - TabView init after click on TabItem

Time:04-05

I'm running at the moment in a issue with the TabView under SwiftUI.

I selecting the state of the TabView over a EnvironmentObject (see code below), at this moment everything is fine, but when I click on a tab it switch it but after it it reinitialize the Tabview and the EnvironmentObject will be reset to the old value.

What I do wrong, on iPad it works???

TabBarView.swift

struct TabBarView: View {
    
    @EnvironmentObject var appData: AppDataModel
    
    @State var activeSheet: ActiveSheet? = nil
    
    init() {
        UITabBar.appearance().isTranslucent = true
        UITabBar.appearance().tintColor = UIColor(named: "TH-Accent")
    }
    
    var body: some View {
        tabview
    }
    
    private var tabview: some View {
        TabView(selection: $appData.currentTab) {
            DashboardView()
                .environmentObject(appData)
                .tabItem {
                    Image(systemName: "rectangle.3.group.fill")
                    Text("Dashboard")
                }
                .tag(Tab.dashboard)
            CalenderView()
                .environmentObject(appData)
                .tabItem {
                    Image(systemName: "calendar")
                    Text("Trainings")
                }
                .tag(Tab.calendar)
            GalleryView()
                .environmentObject(appData)
                .tabItem {
                    Image(systemName: "photo.on.rectangle.angled")
                    Text("Galerie")
                }
                .tag(Tab.gallery)
            TeamView()
                .environmentObject(appData)
                .tabItem {
                    Image(systemName: "person.3.fill")
                    Text("Team")
                }
                .tag(Tab.team)
            SettingsView()
                .environmentObject(appData)
                .tabItem {
                    Image(systemName: "gearshape.fill")
                    Text("Einstellungen")
                }
                .tag(Tab.settings)
        }
        .accentColor(Color("TH-Accent"))
        .onAppear {
            print(appData.currentTab)
        }
        .sheet(item: $activeSheet) { item in
            showActiveSheet(item: item)
        }
    }
}

MainView.swift

struct MainView: View {
    
    @EnvironmentObject var appData: AppDataModel
    
    var body: some View {
        Group {
            if UIDevice.isiPhone {
                tabbar
            } else {
                sidebar
            }
        }
        .environmentObject(appData)
        .onOpenURL{ url in
            if (appData.checkDeepLink(url: url)) {
                print("from DEEP")
            }
        }
    }
    
    private var sidebar: some View {
        SidebarView()
    }
    
    private var tabbar: some View {
        TabBarView()
    }
}

MainApp.swift (Starting point of the App)

@main
struct MainApp: App {
    
    @StateObject var appData = AppDataModel()
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    init() {
        var titleFont = UIFont.preferredFont(forTextStyle: .largeTitle) /// the default large title font
        titleFont = UIFont(
            descriptor:
                titleFont.fontDescriptor
                .withDesign(.rounded)? /// make rounded
                .withSymbolicTraits(.traitBold) /// make bold
            ??
            titleFont.fontDescriptor, /// return the normal title if customization failed
            size: titleFont.pointSize
        )
        
        var smallTitleFont = UIFont.preferredFont(forTextStyle: .body) /// the default large title font
        smallTitleFont = UIFont(
            descriptor:
                smallTitleFont.fontDescriptor
                .withDesign(.rounded)? /// make rounded
                .withSymbolicTraits(.traitBold) /// make bold
            ??
            smallTitleFont.fontDescriptor, /// return the normal title if customization failed
            size: smallTitleFont.pointSize
        )
        
        /// set the rounded font
        UINavigationBar.appearance().largeTitleTextAttributes = [.font: titleFont]
        UINavigationBar.appearance().titleTextAttributes = [.font : smallTitleFont]
    }
    
    var body: some Scene {
        WindowGroup {
            MainView()
                .onAppear {
                    //Add and Init some values for the AppDataModel
                }
                .environmentObject(appData)
                .alert(isPresented: $appData.noConnection, content: {
                    Alert(title: Text("Mobile Daten deaktiviert!"), message: Text("Versichere dich ob deine Mobilen Daten oder dein WLAN eingeschalten sind."), primaryButton: .cancel(Text("OK")), secondaryButton: .default(Text("Einstellungen"), action: {
                        if let url = URL(string: "prefs:root=MOBILE_DATA_SETTINGS_ID"), UIApplication.shared.canOpenURL(url) {
                            UIApplication.shared.open(url, options: [:], completionHandler: nil)
                        }
                    }))
                })
        }
    }
}

CodePudding user response:

I solved my problem by creating a single State variable of type Tab and added a gesture to write in the EnvironmentObject. I think it's a workaround and a bug in SwiftUI because I don't initialize the StateObject again.

  • Related