How to pass data between SwiftUI views using NavigationLink - swift

I am engaging in a small SwiftUI exercise to learn how to pass data between views using NavigationLink. I set up ContentView to send a message to the SecondView after tapping the ContentView NavigationLink. Tapping NavigationLink in the SecondView then sends the message to the ThirdView. However, I am noticing a strange UI occurrence by the time I get to ThirdView. See the screenshot below:
Any idea why this NavigationView issue is occurring? Is it related to having NavigationView in all 3 views?
Here is my code:
ContentView
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: SecondView(message: "Hello from ContentView")) {
Text("Go to Second View")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
SecondView
struct SecondView: View {
var message: String
var body: some View {
Text("\(message)")
NavigationView {
NavigationLink(destination: ThirdView(message: self.message)) {
Text("Go to Third View")
}
}
}
}
struct SecondView_Previews: PreviewProvider {
static var previews: some View {
SecondView(message: String())
}
}
ThirdView
struct ThirdView: View {
var message: String
var body: some View {
NavigationView {
Text("\(message)")
}
}
}
struct ThirdView_Previews: PreviewProvider {
static var previews: some View {
ThirdView(message: String())
}
}
Feedback is appreciated. Thanks!

remove the second navigation view
struct SecondView: View {
var message: String
var body: some View {
VStack(spacing: 100 ) {
Text("\(message)")
NavigationLink(destination: ThirdView(message: self.message)) {
Text("Go to Third View")
}
}
}
}
struct ThirdView: View {
var message: String
var body: some View {
Text("\(message)")
}
}

Related

I cannot navigate deeper into the views in Swiftui

I have three views in my project - ContentView, SecondView, ThirdView
I want to navigate from contentView to secondView and secondView to thirdView.
ContentView :-
import SwiftUI
struct ContentView: View {
#State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
Button {
path.append("SecondView")
} label: {
Text("This is the first view")
}
.navigationDestination(for: String.self) { view2 in
if view2 == "SecondView" {
SecondView()
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
SecondView :-
import SwiftUI
struct SecondView: View {
#State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
Button {
path.append("ThirdView")
} label: {
Text("This is the second view")
}
.navigationDestination(for: String.self) { view2 in
if view2 == "ThirdView" {
ThirdView()
}
}
}
}
}
struct SecondView_Previews: PreviewProvider {
static var previews: some View {
NavigationStack {
SecondView()
}
}
}
ThirdView :-
import SwiftUI
struct ThirdView: View {
var body: some View {
Text("This is the third view")
}
}
struct ThirdView_Previews: PreviewProvider {
static var previews: some View {
NavigationStack {
ThirdView()
}
}
}
What is happening :-
Whenever I tap on the "This is the first view" button in my ContentView, I am navigated to SecondView and automatically navigated back to contentView.
What I want :-
I want to navigate from contentView to secondView and secondView to thirdView.
You shouldn't have multiple NavigationStacks in the hierarchy. You should have one and pass the path via a Binding.
struct ContentView: View {
#State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
Button {
path.append("SecondView")
} label: {
Text("This is the first view")
}
.navigationDestination(for: String.self) { view in
switch view {
case "SecondView":
SecondView(path: $path)
case "ThirdView":
ThirdView()
default:
Text("Unknown")
}
}
}
}
}
struct SecondView: View {
#Binding var path: NavigationPath
var body: some View {
Button {
path.append("ThirdView")
} label: {
Text("This is the second view")
}
}
}
struct ThirdView: View {
var body: some View {
Text("This is the third view")
}
}
struct SecondView_Previews: PreviewProvider {
static var previews: some View {
NavigationStack {
SecondView(path: .constant(NavigationPath()))
}
}
}

Navigation From Right To Left In SwiftUI

As written in the title i am trying to find a way to change the navigation style from left-to-right to a right-to-left Arabic style.
This is a simple NavigationView code I made:
import SwiftUI
struct HomeView: View {
var body: some View {
NavigationView {
List {
NavigationLink(destination: Text("Destination")) {
Text("Go To Destination")
}
}
.navigationTitle("Text")
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}

Trouble getting EnvironmentObject to update the UI

I originally posted another question asking this in the context of a project I was trying to develop, but I can't even get it to work in a vacuum so I figured I'd start with the basics. As the title suggests, my EnvironmentObjects don't update the UI as they should; in the following code, the user enters text on the ContentView and should be able to see that text in the next screen SecondView.
EDITED:
import SwiftUI
class NameClass: ObservableObject {
#Published var name = ""
}
struct ContentView: View {
#StateObject var myName = NameClass()
var body: some View {
NavigationView {
VStack {
TextField("Type", text: $myName.name)
NavigationLink(destination: SecondView()) {
Text("View2")
}
}
}.environmentObject(myName)
}
}
struct SecondView: View {
#EnvironmentObject var myself: NameClass
var body: some View {
Text("\(myself.name)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(NameClass())
}
}
However, the SecondView doesn't show the text that the user has written, but the default value of name (blank). What am I doing wrong here?
class NameClass: ObservableObject {
#Published var name = ""
}
struct ContentView: View {
#StateObject var myName = NameClass()
var body: some View {
NavigationView {
VStack {
TextField("Type", text: $myName.name)
NavigationLink(destination: SecondView()) {
Text("View2")
}
}
}.environmentObject(myName)
}
}
struct SecondView: View {
#EnvironmentObject var myself: NameClass
var body: some View {
Text("\(myself.name)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(NameClass())
}
}

Weird list view when I add navigationBarItem

to make it short: I want to have the same view of the list like in the first image i shared. But when I add a navigation bar item the list looks strange to me. It this a bug of the new version of Swift/XCode or needs something to be changed?
Code:
import SwiftUI
import CoreData
struct ContentView: View {
var body: some View {
NavigationView {
List{
Text("test1")
Text("test2")
Text("test3")
}
.navigationTitle("Test")
// .navigationBarItems(leading:
// Text("Test")
// )
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Try using .navigationViewStyle as below:
struct ContentView: View {
#State private var isFullScreen = false
var body: some View {
NavigationView {
List{
Text("One")
Text("Two")
}
.navigationTitle("Testt")
.navigationBarItems(leading: Text("Add"))
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
Hey! Give This A Try!
var body: some View {
NavigationView {
List{
Text("One")
Text("Two")
}
.navigationTitle("Testt, displayMode: .inline)
.navigationBarItems(leading: Text("Add"))
}
}
}

SwiftUI can't create navigationview

I'm following through some swiftUI tutorial and I couldn't figure out what this meant.
This was the very first step, and I haven't done anything other than adding the NavigationView. How do I resolve this?
That's just container, you need some content inside, If you are just trying something out try following:
var body: some View {
NavigationView {
Text("Testing")
}
}
You cannot have an empty NavigationView. Add something inside.
struct ContentView: View {
var body: some View {
NavigationView {
Text("Text here")
}
}
}
FIRST: Add new SwiftUI-View (Name: MapView.swift without code-changing )
SECOND: Add new SwiftUI-View (Name: SecondView.swift)
THEN Change ContentView and SecondView:
a) ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
MapView() // on upper Screen will appear: "Hello World"
NavigationView {
NavigationLink(destination: SecondView()) {
VStack {
Text("click here")
.fontWeight(.heavy)
.font(.largeTitle)
.padding()
Text("go to screen II")
}
}
} //End of NavigationView
}// End of VStack
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
VStack {
ContentView()
}
}
}
b) SecondView.swift
import SwiftUI
struct SecondView: View {
var body: some View {
VStack {
Text("Screen II")
.fontWeight(.heavy)
.foregroundColor(.blue)
.font(.largeTitle)
.padding()
Text("you changed it")
Text("GRATULATION!")
}
}
}
struct SecondView_Previews: PreviewProvider {
static var previews: some View {
SecondView()
}
}
c) MapView.swift
import SwiftUI
struct MapView: View {
var body: some View {
Text(/*#START_MENU_TOKEN#*/"Hello, World!"/*#END_MENU_TOKEN#*/)
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapView()
}
}