Navigate to another screen in swiftUI - swiftui

Below is the code i am trying to push to another swiftUI when button in swiftUI is pressed.
But it is not navigating to another screen
let controller = DestinationHostingController(rootView: AnotherSwiftUI())
pushViewController(controller, animated: animated)

In SwiftUI, the navigation has been improved,
You have to embed your view inside a NavigationView,
and after that you can use NavigationLink to redirect wherever you want
example:
struct ContentView: View {
var body: some View {
NavigationView {
VStack(spacing: 30) {
Text("You're going to flip a coin – do you want to choose heads or tails?")
NavigationLink(destination: ResultView(choice: "Heads")) {
Text("Choose Heads")
}
NavigationLink(destination: ResultView(choice: "Tails")) {
Text("Choose Tails")
}
}
.navigationTitle("Navigation")
}
}
}
(You can replace the NavigationLink content by whatever you want, Text -> Button)

Related

SwiftUI - NavigationLink and NavigationStack is not working with a button for iOS 16

I am making an app where I need to navigate to the home page when the user clicks on the Login button and when the Login button is clicked, the navigation link code is not working and shows a warning as Result of 'NavigationLink<Label, Destination>' initializer is unused. FYI, please refer to the attached screenshot and the below code:
import SwiftUI
struct LoginView: View {
var nextButton: some View {
HStack {
Button("Next") {
NavigationLink {
HomeView(user: user)
} label: {
Text("Test")
}
}
.buttonStyle(PlainButtonStyle())
.font(.system(size: 24))
}
}
var body: some View {
NavigationStack {
nextButton
}
}
}
There are two problems here:
A NavigationLink is an alternative to a Button and can be used on its own for navigation. You can use a button to navigate programatically, but for this simple case a link works. Like Buttons, you can change the appearance of NavigationLinks if needed.
NavigationStack is a more powerful replacement for NavigationView. You should not mix them both. As the HomeView is your root view, the single NavigationStack for your app should be there (not in the LoginView).
struct HomeView: View {
var body: some View {
NavigationStack {
VStack {
NavigationLink {
LoginView()
} label: {
Text("Login")
}
}
}
}
}
The warning is because you are creating a NavigationLink in the button action code block, and returned NavigationLink is not assigned or used.

How to use NavigationLink inside SwiftUI sheet

I have 4 SwiftUI View:
The FirstView opens the SecondView using a sheet:
.sheet(isPresented: $showSheet) {
SecondView()
}
The SecondView opens the ThirdView using a sheet too:
.sheet(isPresented: $showSheet) {
ThirdView()
}
My expectations: I want ThirdView opens FourthView using NavigationLink (on full screen with Back button in the left corner):
NavigationLink(destination: FourthView()) {
Text("Open FourthView")
}
but I'm having trouble with the view hierarchy. If I want to use NavigationLink, somewhere I have to define NavigationView.
If I define NavigationView in the SecondView like this:
.sheet(isPresented: $showSheet) {
NavigationView {
ThirdView()
}
}
, I have sheet view with Back button, but I want a full screen view with Back button.
Could you help me with this views hierarchy, where should I put NavigationView?

LazyVGrid onTapGesture navigate to next screen swiftUI

I am quite new to swiftUI. I have created a grid view on tapping on which I want to go to next screen. But somehow I am not able to manage to push to next screen. I am doing like this:
var body: some View {
NavigationView {
ScrollView {
LazyVGrid(columns: gridItems, spacing: 16) {
ForEach(viewModel.pokemon) { pokemon in
PokemonCell(pokemon: pokemon, viewModel: viewModel)
.onTapGesture {
NavigationLink(destination: PokemonDetailView(pokemon: pokemon)) {
Text(pokemon.name)
}
}
}
}
}
.navigationTitle("Pokedex")
}
}
Upon doing like this, I am getting a warning stating
Result of 'NavigationLink<Label, Destination>' initializer is unused
Can someone please guide me, how to do this?
.onTapGesture adds an action to perform when the view recognizes a tap gesture. In your case you don't need to use .onTapGesture. If you want to go to another view when cell is tapped you need to write NavigationLink as below.
NavigationLink(destination: PokemonDetailView(pokemon: pokemon)) {
PokemonCell(pokemon: pokemon, viewModel: viewModel)
}
If you want to use .onTapGesture, another approach is creating #State for your tapped cell's pokemon and using NavigationLink's isActive binding. So when user tap the cell it will change the #State and toggle the isActive in .onTapGesture. You may need to add another Stack (ZStack etc.) for this.
NavigationView {
ZStack {
NavigationLink("", destination: PokemonDetailView(pokemon: pokemon), isActive: $isNavigationActive).hidden()
ScrollView {
// ...

SwiftUI: Remove Space above Navigation Bar

I have a simple view hierarchy between two views in SwiftUI.
MainView: This is the top level screen
import SwiftUI
struct MainView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: SearchView()) {
Text("Search")
}
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
}
SearchView:
import SwiftUI
struct SearchView: View {
var body: some View {
Text("Hello, World!")
}
}
I don't want a navigation bar on my main view, but I do want a "back" button on the Search view. This is how the Search view looks:
I don't want the space above the back button - where is that coming from?
I inspected the view hierarchy and it seems the view has TWO UINavigationBar objects. If I hide the navigation bar inside the Search View, the back button goes but the space still remains.
How do I get rid of this unwanted space above the Back button?

Rename Cancel button on a modal sheet

I currently invoke an Example Sentence modal sheet by toggling $showingModal on a certain condition.
.sheet(isPresented: $showingModal) {
ExampleSentence()
}
According to the Human Interface Guidelines, I am able to rename Cancel to something more appropriate such as Dismiss. If I was using UIKit instead of SwiftUI, I'd be using the presentController function which then explains that I can rename the Cancel button using setTitle. https://developer.apple.com/documentation/watchkit/wkinterfacecontroller/1619560-presentcontroller
But if I'm using SwiftUI, is it possible to rename the Cancel button?
EDIT: Sorry I should have clarified that this is a watchOS app. By default it creates a Cancel button in the top left corner but I just want to rename it to dismiss.
You can do that by using a NavigationView within your ExampleSentences view and adding a toolbar to it, something like this.
struct ExampleSentence: View {
#Environment(\.presentationMode) var presentationMode
var body: some View {
NavigationView {
VStack {
Text("Hello View")
}
.navigationBarTitle("Example Sentences")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Done")
}
}
}
}
}
}