Filip
Filip

Reputation: 945

Display grid of images in an Array SwiftUI

I can't use VGrid because unfortunately my deployment target has to be iOS 13. This is what I came up with, but it's not working.

 @State var photoIndex = 0

 func displayPhotoPreview() -> some View {
        self.photoIndex += 1

        print(photoIndex)
        return PhotoPreview(url: photos[self.photoIndex].urls.regular)
            .onTapGesture {
                isPresented.toggle()
                self.selectedPhoto = photos[self.photoIndex]
            }
    }
 ScrollView(.vertical, showsIndicators: false) {
                ForEach(0 ..< photos.count / 3, id: \.self) { _ in
                    HStack(spacing: 15) {
                        ForEach(0 ..< 3, id: \.self) { _ in
                            if self.photoIndex < photos.count {
                                displayPhotoPreview()
                            }
                        }
                    }
                }
                .padding(20)
                .sheet(item: $selectedPhoto) { selectedPhoto in
                    PhotoDetail(photo: selectedPhoto)
                }
            }

The print statement prints each number 30 times (there's thirty images)

Upvotes: 0

Views: 796

Answers (1)

George
George

Reputation: 30361

The problem is that you are changing the @State variable photoIndex 30 times (since there are 30 images). You will have also probably got the following runtime warning:

Modifying state during view update, this will cause undefined behavior.

To fix this, just get the index by calculating it out from the index of the ForEachs.

Remove the photoIndex state variable. Code:

ScrollView(.vertical, showsIndicators: false) {
    ForEach(0 ..< photos.count / 3, id: \.self) { row in
        HStack(spacing: 15) {
            ForEach(0 ..< 3, id: \.self) { column in
                displayPhotoPreview(at: row * 3 + column)
            }
        }
    }
    .padding(20)
    .sheet(item: $selectedPhoto) { selectedPhoto in
        PhotoDetail(photo: selectedPhoto)
    }
}
func displayPhotoPreview(at photoIndex: Int) -> some View {
    print(photoIndex)
    return PhotoPreview(url: photos[photoIndex].urls.regular)
        .onTapGesture {
            isPresented.toggle()
            self.selectedPhoto = photos[photoIndex]
        }
}

Upvotes: 1

Related Questions