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.