In my app, I have a View which is set to either a login View or a home TabView, depending on if the user is logged in. From the TabView, the user can go to a profile popover and logout. I want to switch back to the login View from this popover.
I tried dismissing the popover and immediately logging the user out, but when I test on a real device, what happens is the popover stays on the screen and also no longer responds to user input. It can't be dismissed. I'm not sure why, and what should I do instead?
Starting View:
struct StartView: View {
@EnvironmentObject var authService:AuthService
var body: some View {
ZStack {
if(!authService.signedIn) {
LoginView()
} else {
HomeView()
}
}
}
}
Home TabView:
import SwiftUI
struct HomeView: View {
@State private var showingProfilePopover:Bool = false
var body: some View {
TabView {
NavigationView {
VStack(alignment: .leading) {
Text("Tab 1")
.padding(.leading, 30)
}
.toolbar {
ToolbarItem {
Button(action: {
showingProfilePopover = true
}, label: {
Image(systemName: "person.crop.circle").imageScale(.large)
}
)
}
}
}.popover(isPresented: $showingProfilePopover) {
ProfileView(isPresented: $showingProfilePopover)
}
.tabItem {
Image(systemName: "list.bullet")
.font(.system(size: 26))
Text("Tab 1")
}
NavigationView {
VStack(alignment: .leading) {
Text("Tab 2")
}
}.tabItem {
Image(systemName: "books.vertical")
.font(.system(size: 26))
Text("Tab 2")
}
}
}
}
Popover:
struct ProfileView: View {
@EnvironmentObject var authService:AuthService
@Binding var isPresented: Bool
var body: some View {
Button("Logout") {
// Close the popup and switch to LoginView
print("Tapped logout")
isPresented = false
authService.signOut()
}
.font(Font.custom("OpenSans-Regular", size: 18))
.padding(20)
}
}
LoginView:
import SwiftUI
struct LoginView: View {
@EnvironmentObject var authService:AuthService
var body: some View {
VStack {
Button("Login") {
self.authService.signIn()
}.buttonStyle(.borderedProminent)
}
}
}
AuthService:
import SwiftUI
class AuthService: ObservableObject {
@Published var signedIn:Bool
init(signedIn:Bool) {
self.signedIn = signedIn
}
func signIn() {
self.signedIn = true
}
func signOut(){
self.signedIn = false
}
}
Seems like an issue connected to .popover
. I can reproduce the issue, but it works just fine using .sheet
instead.
Consider attaching the .popover
on the TabView
or the Button
itself then it seems to work just fine.