Reputation: 230
I have a weird issue, where I navigate to EditView
and edit a state variable from ContentView
. After that I dismiss EditView
with presentation.wrappedValue.dismiss()
. The problem is, as soon as the view is dismissed, it reappears again.
I'm using XCode 12.4 and my iOS deployment target is set to 14.4
Observations:
EditView
doesn't reappear if the value isn't editedText("Value: \(title)")
>> Text("Value")
from ContentView
tree resolves the issue, but that obviously isn't a solution.NavigationLink
from .toolbar
e.g. VStack {
Text("Value: \(title)")
NavigationLink(destination: EditView(title: $title)){
Text("Edit")
}
}
also resolves the issue, but that seems like a hack. Besides, I'd like to keep using .toolbar
because I like the .navigationTitle
animation and I can't have a button in the upper-right corner of the screen if I have a navigation title without the toolbar.
Here's the full code:
import SwiftUI
struct ContentView: View {
@State var title: String = "Title"
@State var isActive: Bool = false
var body: some View {
NavigationView {
Text("Value: \(title)")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink(destination: EditView(title: $title, isActive: $isActive), isActive: $isActive){
Text("Edit")
}
}
}
}
}
}
struct EditView: View {
@Environment(\.presentationMode) var presentation
@Binding var title: String
@Binding var isActive: Bool
var body: some View {
Button(action: {
title = "\(Date().timeIntervalSince1970)"
// presentation.wrappedValue.dismiss()
isActive = false
}){
Text("Done")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
As far as I can tell this is a .toolbar
bug, and if it turns out that way I'll report it to Apple, but in the meantime, does anyone have a better solution and/or explanation for this?
Cheers!
EDIT:
I updated the code with isActive
value for the NavigationLink
. It doesn't work when written like that, but uncommenting the commented out line makes it work. But that's quite hacky.
Upvotes: 0
Views: 2138
Reputation: 2882
You are mixing up 2 things NavigationLink
will push the view on stack
, just like NavigationController
in swift. That’s why you can see back button after navigating to second view. When you hit back button, it will pop top most view out of stack
. presentationMode
is not needed , dismissing presented view will not pop it of the stack.
To present a view and dismiss it you can check below code.
import SwiftUI
struct ContentViewsss: View {
@State var title: String = "Title"
@State var isPresented = false
var body: some View {
NavigationView {
Text("Value: \(title)")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
isPresented.toggle()
}){
Text("Edit")
}
}
}
}.sheet(isPresented: $isPresented, content: {
EditView(title: $title, state: $isPresented)
})
}
}
struct EditView: View {
@Binding var title: String
@Binding var state: Bool
var body: some View {
Button(action: {
title = "\(Date().timeIntervalSince1970)"
state.toggle()
}){
Text("Done")
}
}
}
If you want NavigationLink
functionality, you can just remove presentationMode
code from second view, and keep ContentView
as it is -:
struct EditView: View {
//@Environment(\.presentationMode) var presentation
@Binding var title: String
var body: some View {
Button(action: {
title = "\(Date().timeIntervalSince1970)"
// presentation.wrappedValue.dismiss()
}){
Text("Done")
}
}
}
Upvotes: 1