Reputation: 437
I have a problem to switch to another view without pressing a button in my SwiftUI app. I can take many examples of what I want to do : 1- Imagine a login form where we need to fill 2 textfields : username and password. When there's a perfect match we are automatically authenticated. 2- Take my example now. I have this view :
What I want to do : when I select a row in the list (ex. Lyon-Perrache TGV) AND if the two textfields are not empty => I'm redirected to another view.
There's many examples to know how to move to a view from another one, but always with a button click .. (with NavigationLink) I need to do this programatically exactly when the two textfields are filled AND when I select the destination textfield from the list.
that's a part of my code :
import SwiftUI
struct Search: View {
@ObservedObject var webservice = Webservice()
@State var Depart: String = ""
@State var Destination: String = ""
@State var listStation = [Station]()
@State var predictedValues: Array<String> = []
@State var isBeingEditedDeparture: Bool = false
@State var isBeingEditedDestination: Bool = false
@State var hey: Bool = false
@State var activate: Bool = false
init() {
UITableView.appearance().showsVerticalScrollIndicator = false
UITableView.appearance().backgroundColor = .clear
UITableViewCell.appearance().backgroundColor = .clear
//UITableView.appearance().separatorColor = .clear
}
var body: some View {
VStack(alignment: .leading){
PredictingTextField(listStation: self.$listStation , predictedValues: self.$predictedValues,
Depart: self.$Depart, Destination: self.$Destination, isBeingEditedDeparture:
self.$isBeingEditedDeparture, isBeingEditedDestination: self.$isBeingEditedDestination )
.textFieldStyle(RoundedBorderTextFieldStyle())
List() {
ForEach(self.predictedValues, id: \.self){ value in
Text(value)
.onTapGesture {
if(self.isBeingEditedDeparture == true)
{
self.Depart = value
}
else{
self.Destination = value
self.activate = true
}
}
}
}.padding(.top, 10)
}
}
I have declared a variable named "activate" to be the trigger point of moving to the new View. It's equal to true when we select a row in the list for "destination" textfield.
How can I do to go further ?
Thank you in advance !
Upvotes: 6
Views: 5717
Reputation: 47
The idea is something about this:
When isActive comes true, NavigationLink is activated and goes to destination, like if you click on content inside NavigationLink() { content() }
struct SomeView: View {
@State private var isActive = false
NavigationView {
NavigationLink(
destination: ViewThatOpensWhenIsActiveComesTrue(),
isActive: $isActive
) {
// your custom case that u talking about in question
// for example, with button its can be used like that:
Button("Activate isActive") {
isActive = true
}
}
}
}
Upvotes: 0
Reputation: 54426
Note: Below is a simplified example of how to programatically present a new link. For a more advanced generic example please see this answer.
In iOS 16 we can access the NavigationStack and NavigationPath that allow us to push views programmatically.
struct ContentView: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
Text("ContentView")
.navigationDestination(for: String.self) { view in
if view == "NewView" {
Text("NewView")
}
}
}
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
path.append("NewView")
}
}
}
}
In the above example you can trigger the NewView
to appear just by executing path.append("NewView")
from any place.
You can use a NavigationLink
with the isActive
parameter. When you set this parameter to true
it will present a NewView
:
@State var activated: Bool = false
NavigationLink(destination: NewView(), isActive: $activated) {
EmptyView()
}
Then you need to place your NavigationLink
in the NavigationView
to make it work.
Upvotes: 10