'NavigationLink inside LazyVGrid cycles all entries on back, SwiftUI
I have an image grid. Each image on tap should push a view on the NavigationView with the image details.
The navigation link works as intended, but when I press the back button it opens the next image and so on until it has cycled all the images. What is going on?
This is the View
:
struct ImageGrid: View {
@ObservedObject var part: Part
@State private var showingImagePicker = false
@State private var inputImage: UIImage?
var body: some View {
Button("add images"){
self.showingImagePicker = true
}
LazyVGrid(columns: [GridItem(.adaptive(minimum:100))]){
ForEach(part.images){ image in
ZStack {
Image(uiImage: image.thumb)
.resizable()
.scaledToFit()
NavigationLink (
destination: ImageDetail(image:image),
label: {
EmptyView()
}
).buttonStyle(PlainButtonStyle())
}
}
}
.sheet(isPresented: $showingImagePicker, onDismiss: loadImage) {
ImagePicker(image: self.$inputImage)
}
}
// other functions ...
...
}
and this is the detail View
struct ImageDetail: View {
@ObservedObject var image: TrainingImage
var body: some View {
VStack {
Image(uiImage: image.content)
.resizable()
.scaledToFit()
}
}
}
EDIT:
This is a self-contained example isolating the behaviour. It seems to stop working correctly when the grid is inside a form section. Eliminating the form and the section the navigation link works correctly
import SwiftUI
extension String: Identifiable {
public var id:Int {
self.hashValue
}
}
struct ImageDetail: View {
var image: String
var body: some View {
VStack {
Image(uiImage: UIImage(systemName: image)!)
.resizable()
.scaledToFit()
}
}
}
struct ContentView: View {
@State var images:[String] = ["plus", "minus"]
var body: some View {
NavigationView {
Form {
Section {
LazyVGrid(columns: [GridItem(.adaptive(minimum:100))]){
ForEach(images){ image in
NavigationLink (
destination: ImageDetail(image: image),
label: {
Image(uiImage: UIImage(systemName: image)!)
.resizable()
.scaledToFit()
}
).buttonStyle(PlainButtonStyle())
}
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Solution 1:[1]
It is Form/List feature to auto-detect links in rows, but you have several in row, so the effect. The solution would be to separate cell view and hide link from auto-detection.
Tested with Xcode 12.0 / iOS 14
struct ContentView: View {
@State var images:[String] = ["plus", "minus"]
var body: some View {
NavigationView {
Form {
Section {
LazyVGrid(columns: [GridItem(.adaptive(minimum:100))]){
ForEach(images){
ImageCellView(image: $0)
}
}
}
}
}
}
}
struct ImageCellView: View {
var image: String
@State private var isActive = false
var body: some View {
Image(uiImage: UIImage(systemName: image)!)
.resizable()
.scaledToFit()
.onTapGesture {
self.isActive = true
}
.background(
NavigationLink (
destination: ImageDetail(image: image), isActive: $isActive,
label: {
EmptyView()
}
))
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |