ios – LazyVGrid merchandise hit take a look at space will not be anticipated

ios – LazyVGrid merchandise hit take a look at space will not be anticipated


I’m studying SwiftUI and attempting to impl a photograph gallery app, utilizing LazyVGrid.
Within the ForEach loop of my ContentView’s physique() technique, I’ve a thumbnail view for every picture fetched from the library.

import SwiftUI
import Pictures
import CoreImage
import ImageIO
import AVKit
import AVFoundation

struct Content material: Identifiable {
    let id = UUID()
    let phAsset: PHAsset
    let index: Int
}

struct ContentView: View {
    @State personal var contents: [Content] = []
    @State personal var selectedContent: Content material? = nil
    @State personal var isLoading: Bool = true

    var physique: some View {
        NavigationView {
            let minItemWidth: CGFloat = 100
            let spacing: CGFloat = 2
            let screenWidth = UIScreen.principal.bounds.width
            let columns = Int((screenWidth + spacing) / (minItemWidth + spacing))
            let totalSpacing = spacing * CGFloat(columns - 1)
            let itemWidth = (screenWidth - totalSpacing) / CGFloat(columns)
            ZStack {
                ScrollView {
                    LazyVGrid(columns: [GridItem(.adaptive(minimum: 100))], spacing: 2) {
                        ForEach(contents) { content material in
                            ThumbnailView(content material: content material.phAsset)
                                .body(width: itemWidth, peak: itemWidth)
                                .onTapGesture {
                                    selectedContent = content material
                                }
                                .padding(4)
                                .background(Shade.blue.opacity(0.5))
                                .clipped()
                        }
                    }
                    .padding(2)
                }
                .navigationTitle("Pictures Library")
                .onAppear(carry out: loadContents)
                .sheet(merchandise: $selectedContent) { content material in
                    NavigationView {
                        DetailImageView(asset: content material.phAsset)
                            .navigationBarItems(trailing: Button("Achieved") {
                                selectedContent = nil
                            })
                    }
                }

                if isLoading {
                    ProgressView("Loading...")
                        .progressViewStyle(CircularProgressViewStyle())
                        .scaleEffect(1.5, anchor: .heart)
                }
            }
        }
    }

    func loadContents() {
        PHPhotoLibrary.requestAuthorization { standing in
            if standing == .approved {
                fetchContents()
            }
        }
    }

    func fetchContents() {
        let fetchOptions = PHFetchOptions()

        DispatchQueue.international(qos: .background).async {
            self.isLoading = true
            let fetchResult = PHAsset.fetchAssets(with: fetchOptions)
            var fetchedContents: [Content] = []
            var index = 0
            fetchResult.enumerateObjects { (phAsset, _, _) in
                fetchedContents.append(Content material(phAsset: phAsset, index: index))
                index += 1
            }
            self.isLoading = false

            DispatchQueue.principal.async {
                contents = fetchedContents
            }
        }
    }
}

struct ThumbnailView: View {
    let content material: PHAsset
    @State personal var picture: UIImage? = nil

    var physique: some View {
        Group {
            if let picture = picture {
                Picture(uiImage: picture)
                    .resizable()
                    .scaledToFill()
            } else {
                Shade.grey
            }
        }
        .onAppear(carry out: loadImage)
    }

    func loadImage() {
        let imageManager = PHImageManager.default()
        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = false
        imageManager.requestImage(for: content material, targetSize: CGSize(width: 100, peak: 100), contentMode: .aspectFill, choices: requestOptions) { (picture, _) in
            self.picture = picture
        }
    }
}

struct DetailImageView: View {
    let asset: PHAsset
    @State personal var picture: UIImage?

    var physique: some View {
        Group {
            if let picture = picture {
                Picture(uiImage: picture)
                    .resizable()
                    .aspectRatio(contentMode: .match)
                    .edgesIgnoringSafeArea(.all)
            } else {
                ProgressView()
            }
        }
        .onAppear(carry out: loadFullImage)
    }

    func loadFullImage() {
        let supervisor = PHImageManager.default()
        let choices = PHImageRequestOptions()
        choices.deliveryMode = .highQualityFormat
        choices.isNetworkAccessAllowed = true

        supervisor.requestImage(
            for: asset,
            targetSize: PHImageManagerMaximumSize,
            contentMode: .aspectFit,
            choices: choices
        ) { end result, _ in
            picture = end result
        }
    }
}

The issue is that once I click on on sure space of an merchandise, the opened merchandise will not be anticipated. I attempted debugging this challenge for a complete day and located if I remark out the “.clipped()” modifier on the ThumbnailView, I can see the merchandise views of the LazyVGrid is overlapped, that’s the reason why the view on prime is opened aside from the view I assumed I clicked. That is fairly unusual to me as I imagine if I specify the scale of a view by .body() modifier, it shouldn’t be in a position to obtain any contact occasion exterior the world.

I’m new to SwiftUI and iOS programming, any assist may be very appreciated.

Leave a Reply

Your email address will not be published. Required fields are marked *