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.