SwiftUI: How can I get the selected row in a List before pushing another view
Solution 1
Alright, I found a not too shady solution.
I used this article https://ryanashcraft.me/swiftui-programmatic-navigation shout out to him!
Instead of using a NavigationLink
button, I use a regular button, save the selected item when the user tap then use NavigationDestinationLink
to push the new view as is self.link.presented?.value = true
.
Works like a charm as of beta 3! I'll update my post if something change in the next betas.
Here's how it could look like:
struct AnotherView : View {
private let link: NavigationDestinationLink<AnotherView2>
@State var viewModel = AnotherViewModel()
init() {
self.link = NavigationDestinationLink(
AnotherView2(),
isDetail: true
)
}
var body: some View {
NavigationView {
VStack {
List(viewModel.items.identified(by: \.id)) { item in
Button(action: {
// Save the object into a global store to be used later on
self.viewModel.selectedItem = item
// Present new view
self.link.presented?.value = true
}) {
Text(value: item)
}
}
}
}
}
}
Solution 2
You can add simple TapGesture
NavigationLink(destination: ContentView() ) {
Text("Row")
.gesture(TapGesture()
.onEnded({ _ in
//your action here
}))
}
Benjamin Clanet
Updated on April 30, 2020Comments
-
Benjamin Clanet about 4 years
Another SwiftUI struggle!
I have a view that contains a list. When user taps on a row, I want to first save the selected item in my VM then push another view. The only way I can think of to solve that issue is to first save the selected row and have another button to push the next view. It seems impossible to do this with only one tap.
Anyone have a clue?
Here's the code by the way:
struct AnotherView : View { @State var viewModel = AnotherViewModel() var body: some View { NavigationView { VStack { List(viewModel.items.identified(by: \.id)) { item in NavigationLink(destination: DestinationView()) { Text(item) } // Before the new view is open, I want to save the selected item in my VM, which will write to a global store. self.viewModel.selectedItem = item } } } } }
Thank you!
-
P. Ent over 4 yearsIf you could possibly update this now that NavigationDestinationLink has been deprecated in the first SwiftUI release, that would be tremendously helpful.
-
Ben over 4 yearsYou can just use
.onTapGesture { /* actions here */ }
instead of.gesture(TapGesture()).onEnded({ ... })
-
malhal over 4 yearscan onReceive be used with an @State?
-
Mike W. over 4 years@malhal the entire view is invalidated when a
@State
changes, not sure what kind of publisher you would be expecting in that case. I suggest checking out: [stackoverflow.com/a/56462423/1086306] -
malhal over 4 yearsWhen an
@State
changes I wanted to change another@State
if the new value is not nil and is used on another view. I've achieved it by using anObservableObject
implementing class and checking inside the@Published
didSet to set another@Published
but was wondering if there was a simpler way to hook into an@State
e.g. like if we had didSetValue. -
electromaggot over 4 yearsUsing this approach, isn't the "action" only executed if the Text itself is tapped and not the entire row? That is, if the tap is outside of the Text's bounds, I believe the navigation will occur but the "action" will not execute.
-
electromaggot over 4 yearsThanks. I think if you use
Button(action:
with your Text embedded in the button, it does take a tap from the whole row. Actually it was a lot of trouble to get both the action AND destination to work in unison, but was possible by setting a @State Boolean in the action, then testing for that Boolean in aNavigationLink(destination:isActive:)
outside of theList
. It was easier with what Apple deprecated! -
Ivan Titkov over 4 yearsHah agreed, after some experiment with this, I made this designer other way, I just make some action at .onAppearAction ( detailed VC). Btw you can see my implementation here github.com/titkov5/OhTronald at file TagsList -> QuotesList.onAppear()
-
Learn2Code about 4 years@IvanTitkov that doesnt work for a NavigationView with a List of items
-
Ivan Titkov about 4 years@Learn2Code what exactly?
-
Learn2Code about 4 years@IvanTitkov putting a gesture when its in a NavigationView and part of a List. It works only when its one NavigationLink only. I think Apple should fix the NavigationView when its in a List to execute the gesture as well.
-
Ribena about 3 yearsthis doesn't appear to answer the question!