Comments (9)
Hi @ch05enOne, if you can use @StateObject
(i.e. you can target iOS >= 14) it's a good idea to inject state objects from the outside. You can even inject the entire NavigationStack
as a @StateObject
in your NavigationStackView
like this (this is just an example):
@main
struct SwiftUIExamplesApp: App {
@StateObject var navigationStack = NavigationStack()
var body: some Scene {
WindowGroup {
NavigationStackView(navigationStack: navigationStack) {
ContentView()
}
}
}
}
Then you can access and use the navigationStack
:
- as usual (i.e. from your view hierarchy by the
@EnvironmentObject
property) - or referring to it from where you store it (in the example above it is stored in the "main" struct of the app): let's say you are in a specific view of your project, you can do something like:
theObjectContainingNavStack.navigationStack.push(...)
Let me know if you manage to solve your issue.
Matteo
from swiftui-navigation-stack.
@matteopuc I had the same issue and can confirm that using a @StateObject
works for me now. Thanks!
from swiftui-navigation-stack.
I tried to stop using fullScreenCover and just using NavigationStack to display the messages but then another issue appeared. It seems that If i aim getting any environmentObject from swift, it will do the same thing. Slightly slide to the right and come back.
from swiftui-navigation-stack.
Hi @ch05enOne would you be able to provide me with a small example of the issue? So that I can copy-paste it on Xcode and try to debug and solve it. Thanks.
Matteo
from swiftui-navigation-stack.
Sure @matteopuc. Just to give you a better prespective, I wrote an issue on here under the name ch05en when I tried to log out the user. You quickly solved that for me. Thanks! This problem has to Do with me using snapshotListeners from Firebase Firestore. Once i log out the app, I want to remove all the snapshotListeners. This isn't a problem though. I have figured this part out. This is the manager where I add and remove the snapshotListeners.
`class StatusManager: ObservableObject{
@Published var listeners: [ListenerRegistration?] = []
func logOut(){
for i in listeners{
if i != nil{
print(listeners.count)
i?.remove()
}
else{
print("Could not remove listener")
}
}
listeners.removeAll()
try? Auth.auth().signOut()
}
}`
I pass this as an environment object for all the views to use in my App.swift file. The basic functionality is that once I initialize the snapshotListener, I append it to the listeners array.
This is the View where I list all the contacts. I use a button to toggle a boolean variable. I use that bool for the PushView.
`
var body: some View {
VStack(spacing:0){
TopBar(profileTrigger: $profTrig)
List{
ForEach(driversArray, id: \.self) { driver in
Button {
showMessages.toggle()
} label: {
AdminProfileCell(email: $email, driverEmail: driver)
}
**PushView(destination: MessageView(email: $email, driver: driver), isActive: $showMessages) {
}**
}
}
}
.accentColor(.black)
.edgesIgnoringSafeArea(.all)
}
`
This is the MessageView, the view that is causing the error. Once I click on the button which pushes to this view, It actually triggers the onAppear() method but comes back right away.
`struct MessageView{
@EnvironmentObject var statusManager: StatusManager
@EnvironmentObject private var navStack: NavigationStack
@Binding var email: String
@State var messagesArary: [MessageComp] = []
@State var padding: CGFloat = 0
@State var paddingDirection: Edge.Set = .trailing
@State var viewIsActive: Bool = false // Use this to solve a notification issue. not relevant
@State var messageGetterListener: ListenerRegistration? // snapshotListener
@State var isReadListener: ListenerRegistration? // snapshotListener
@State var firstInstance: Bool = true // Use this so I dont append the listeners array everytime the view appears. I initialize the listeners in onAppear()
var body: some View{
VStack{
HStack{
Button {
self.navStack.pop()
} label: {
Image(systemName: "arrow.left")
.foregroundColor(.white)
.frame(width: 48, height: 48)
}
Spacer()
}.padding(.horizontal)
ScrollView{
ForEach(messagesArray, id: .self){ message in
//Displays all messages
}
}
} .onDisappear(perform: {
viewIsActive.toggle()
firstInstance = false
})
.onAppear(perform: {
viewIsActive.toggle()
if firstInstance{
// Initialize listener
messageGetterListener = db.collection("adminData").document(email).collection("drivers").document(driver).collection("messages").whereField("cv", isEqualTo: 1).order(by: "date", descending: false).addSnapshotListener {...}
// Initialize listener
isReadListener = db.collection("adminData").document(email).collection("drivers").document(driver).collection("messages").whereField("cv", isEqualTo: 1).whereField("sender", isNotEqualTo: email).addSnapshotListener {...}
// THIS causes the bug. If I remove this, everything display wise works perfectly. Otherwise, the bug persists.
statusManager.listeners.append(messageGetterListener)
statusManager.listeners.append(isReadListener)
}
else{}
})
}`
from swiftui-navigation-stack.
Sorry man but I just couldn't get the formatting right. Hope this helps.
from swiftui-navigation-stack.
Unfortunately I can't manage to make your example compile, I miss too many things. It would be really great to have a minimum viable example that reproduces the issue. I'm trying to create it, but I'm not experiencing the problem. For example, take a look at the following (you can copy paste it in your Xcode and try it yourself):
// this is the entry point file
import SwiftUI
import NavigationStack
@main
struct SwiftUIExamplesApp: App {
var body: some Scene {
WindowGroup {
NavigationStackView {
ContentView()
}
.environmentObject(StatusManager())
}
}
}
class StatusManager: ObservableObject{
@Published var listeners: [Int] = []
}
struct ContentView: View {
@EnvironmentObject var statusManager: StatusManager
var body: some View {
VStack {
Text("TOP BAR")
Spacer()
ForEach(statusManager.listeners, id: \.self) { listener in
Text("\(listener)")
}
Spacer()
PushView(destination: ChildView()) {
Text("PUSH")
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.red)
}
}
struct ChildView: View {
@EnvironmentObject var statusManager: StatusManager
var body: some View {
VStack {
Text("asd")
PopView {
Text("POP")
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.green)
.onAppear {
statusManager.listeners.append(10)
}
}
}
Since you told me that the issue is due to these two lines:
statusManager.listeners.append(messageGetterListener)
statusManager.listeners.append(isReadListener)
I tried to do something similar in the onAppear
, but it seems that everything works as expected. Maybe you can take my example and change something trying to make the issue occur.
from swiftui-navigation-stack.
Will do @matteopuc . Thank you
from swiftui-navigation-stack.
@matteopuc This similar library has a similar issue. reopening to see if it helps. https://github.com/rebeloper/NavigationKit/issues/6 I looked at ur injection above for the environment object btw. Not sure if this makes a change, but instead of using .environmentObject(StatusManager()), I initialized a @StateObject variable and injected that into the environment.
from swiftui-navigation-stack.
Related Issues (20)
- Full Screen cover equivalent HOT 4
- Swift Package Manager installation not working - XCode 13 HOT 4
- Stack Reset / Jump to a completely different view HOT 2
- Transition animation not working HOT 1
- @State variables get reset after pop HOT 3
- Support for iOS 15. HOT 1
- Push doesn't work if app is backgrounded and aware of scenePhase
- Return to the same position in the previous view HOT 2
- Support for Xcode 14 and new SwiftUI API HOT 6
- Previous view completely reloaded after pop HOT 1
- Popping to a specific view
- Callback navigation sometimes doesnt work HOT 1
- iOS 16 transitions malfunctioning HOT 9
- after pop,the previous scrollview auto scroll to top? HOT 6
- Xcode 14 Compiling Issue HOT 6
- not support swipe back HOT 2
- Referencing @Environment(\.scenePhase) var scenePhase breaks navigation when moving app to background
- [Bug]: Clicking on any other window in macOS will return stack to its root
- Value not changed by @Binding
- onappear excuse only first time
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from swiftui-navigation-stack.