Navigation Back Button not hidden in SwiftUI - swift

Do you know why the back button still showing after I wrote
.navigationBarBackButtonHidden(true)
it seem that Xcode doesn't read it correctly.
import SwiftUI
import CoreData
struct ContentView: View {
#State var goToHome: Bool = false
var body: some View {
NavigationStack {
VStack {
Welcome(gotoSomewhere: $goToHome)
}
.navigationDestination(isPresented: $goToHome) { Home() }
.navigationBarBackButtonHidden(true) //HERE IS THE NAVIGATIONBAR HIDDEN
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
}
I tried to write an NavigationLink but then shows me the alert:
... was deprecated in iOS 16.0: use NavigationLink(value:label:)
inside a NavigationStack or NavigationSplitView

This modifier .navigationBarBackButtonHidden(true) should be on home.
Home().navigationBarBackButtonHidden(true)
And yes the NavigationLink will be deprecated in the future, it's up to you whether it's important or not to include at the moment in your app.

Related

SwiftUI | Preview not updating on #Binding var value change

I am learning SwiftUI and tried to make a simple todo list but I'm having issues understanding why #Binding property doesn't update my preview.
The code is the following.
import SwiftUI
struct TodoRow: View {
#Binding var todo: Todo
var body: some View {
HStack {
Button(action: {
todo.completed.toggle()
}, label: {
Image(systemName: todo.completed ? "checkmark.square" : "square")
})
.buttonStyle(.plain)
Text(todo.title)
.strikethrough(todo.completed)
}
}
}
struct TodoRow_Previews: PreviewProvider {
static var previews: some View {
TodoRow(todo: .constant(Todo.sampleData[0]))
}
}
The preview doesn't update when I click the square button but the app works fine. Am I using it incorrectly?
EDIT:
Even without .constant(#), the preview doesn't work.
struct TodoRow_Previews: PreviewProvider {
#State private static var todo = Todo.sampleData[0]
static var previews: some View {
TodoRow(todo: $todo)
}
}
Found a solution in the article Testing SwiftUI Bindings in Xcode Previews.
In order for previews to change you must create a container view that holds state and wraps the view you're working on.
In my case what I've ended up doing was changing my preview to the following.
struct TodoRow_Previews: PreviewProvider {
// A View that simply wraps the real view we're working on
// Its only purpose is to hold state
struct TodoRowContainer: View {
#State private var todo = Todo.sampleData[0]
var body: some View {
TodoRow(todo: $todo)
}
}
static var previews: some View {
Group {
TodoRow(todo: .constant(Todo.sampleData[0]))
.previewDisplayName("Immutable Row")
TodoRowContainer()
.previewDisplayName("Mutable Row")
}
}
}

How to fix TextField popping back to root on cancel?

I have a simple test watchOS application with a TextField in a secondary view (navigated to from a NavigationLink).
However, when the TextField is canceled or submitted, it will pop back out to the root view instead of staying in the current view. I can't find any information on this anywhere else. Any fixes?
ContentView:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView{
NavigationLink("what", destination: DestinationView())
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
DestinationView:
import SwiftUI
struct DestinationView: View {
#State private var message: String = ""
var body: some View {
TextField(
"Send Something...",
text: $message
)
}
}
struct DestinationView_Previews: PreviewProvider {
static var previews: some View {
DestinationView()
}
}
I found the issue..
I was using a NavigationView, which is deprecated. I removed it and now it's working as intended. (XCode 13.2.1, watchOS 8.3)
*facepalm*

Swiftui how to open page as in segue type model

I need to navigate my page and open it like this
I was doing this in my previous app by performSegue like this
self.performSegue(withIdentifier: "goToResult", sender: self)
But now i am using SwiftUI so i need to know how can i achieve this
I am calling my page simple like this
NavigationLink(destination: LoginScreenView()) {
Text("Go To Next Step")
}
And the other page is
struct LoginScreenView: View {
var body: some View {
NavigationView {
Text("Hello, World!")
}
}
}
struct LoginScreenView_Previews: PreviewProvider {
static var previews: some View {
LoginScreenView()
.previewDevice("iPhone 11")
.previewInterfaceOrientation(.portrait)
}
}
I was learning some couse on udemy that use UIView but I am now using SwiftUI and stuck on this navigation how can I achieve this type of model navigation on this(Simple Navigation is wokring fine)
Use .sheet
// for example
NavigationView{}.sheet(isPresented: $showingSheet) {
LoginScreenView()
}
Here showingSheet is a state:
#State private var showingSheet = false
Set this state to true, to open a new page.

SwiftUI sheet gets dismissed the first time it is presented

This bug is driving me insane. Sometimes (well most of the time) presented sheet gets dismissed first time it is opened. This is happening only on a device and only the first time the app is launched. Here is how it looks on iPhone 11 running iOS 14.1 built using Xcode 12.1 (can be reproduced on iPhone 7 Plus running iOS 14.0.1 as well):
Steps in the video:
I open app
Swiftly navigate to Details view
Open Sheet
Red Sheed gets dismissed by the system???
I open sheet again and it remains on the screen as expected.
This is SwitUI App project (using UIKIt App Delegate) and deployment iOS 14. Code:
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: DetailsView()) {
Text("Open Details View")
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct DetailsView: View {
#State var sheetIsPresented: Bool = false
var body: some View {
VStack {
Button("Open") {
sheetIsPresented.toggle()
}
}.sheet(isPresented: $sheetIsPresented, content: {
SheetView()
})
}
}
struct SheetView: View {
var body: some View {
Color.red
}
}
I was able to fix this problem by removing line .navigationViewStyle(StackNavigationViewStyle()), but I need StackNavigationViewStyle in my project. Any help will be appreciated.
Updated: There is a similar post on Apple forum with sheet view acting randomly weird.
One solution that I found is to move sheet to the root view outside NavigationLink (that would be ContentView in my example), but that is not ideal solution.
I had the same problem in an app. After a great deal of research, I found that making the variable an observed object fixed the problem in SwiftUI 1, and it seems to be in SwiftUI 2. I do remember that it was an intermittent problem on an actual device, but it always happened in the simulator. I wish I could remember why, maybe when the sheet appears it resets the bound variable?, but this code fixes the problem:
import SwiftUI
import Combine
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: DetailsView()) {
Text("Open Details View")
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct DetailsView: View {
#ObservedObject var sheetIsPresented = SheetIsPresented.shared
var body: some View {
VStack {
Button("Open") {
sheetIsPresented.value.toggle()
}
}.sheet(isPresented: $sheetIsPresented.value, content: {
SheetView()
})
}
}
struct SheetView: View {
var body: some View {
Color.red
}
}
final class SheetIsPresented: NSObject, ObservableObject {
let objectWillChange = PassthroughSubject<Void, Never>()
static let shared = SheetIsPresented()
#Published var value: Bool = false {
willSet {
objectWillChange.send()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Tested on Xcode 12.1, iOS 14.1 in simulator.
Just add your NavigationView view to bellow code line
.navigationViewStyle(StackNavigationViewStyle())
Example :
NavigationView { }.navigationViewStyle(StackNavigationViewStyle())
Problem will be solved (same issues I was faced)

Why View.onDisappear not get called?

In iOS 13 beta 4, all View.onDisappear do not get called.
There is a navigation view and push to a Detail View. When a user tap navigation back button, the DetailView.onDisappear not get called.
How to fix it?
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: DetailView()) { Text("show") }
}
}
}
struct DetailView : View {
var body: some View {
Text("here")
.onDisappear {
print("onDisappear")
}
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
In the current beta onAppear() works great but onDisappear() doesn’t seem to get called.