SwiftUI 点击手势选择错误的项目

Lui*_*rez 10 swiftui

所以我正在尝试创建一个自定义图像选择器,类似于 Instagram,但更基本。这就是我使用它创建屏幕的方法。

struct NewPostScreen: View {
@StateObject var manager = SelectNewPostScreenManager()

let columns = [GridItem(.flexible(), spacing: 1), GridItem(.flexible(), spacing: 1), GridItem(.flexible(), spacing: 1)]

var body: some View {

    ScrollView {
        VStack(spacing: 1) {
            Image(uiImage: manager.selectedPhoto?.uiImage ?? UIImage(named: "placeholder-image")!)
                .resizable()
                .scaledToFit()
                .frame(width: 350, height: 350)
                .id(1)
            LazyVGrid(columns: columns, spacing: 1) {
                ForEach(manager.allPhotos) { photo in
                    Image(uiImage: photo.uiImage)
                        .resizable()
                        .scaledToFill()
                        .frame(maxWidth: UIScreen.main.bounds.width/3, minHeight: UIScreen.main.bounds.width/3, maxHeight: UIScreen.main.bounds.width/3)
                        .clipped()
                        .onTapGesture {
                            manager.selectedPhoto = photo
                        }
                }
            }
        }
    }
}
}
Run Code Online (Sandbox Code Playgroud)

用户界面看起来不错,一切都很好,但有时当我使用 TapGesture 单击图像时,它会为我的经理提供错误的 selectedPhoto。这是我的经理的样子以及我如何从图库中获取照片。

 class SelectNewPostScreenManager: ObservableObject {
@Environment(\.dismiss) var dismiss
@Published var selectedPhoto: Photo?
@Published var allPhotos: [Photo] = []

init() {
    fetchPhotos()
}

private func assetsFetchOptions() -> PHFetchOptions {
    let fetchOptions = PHFetchOptions()
    let sortDescriptor = NSSortDescriptor(key: "creationDate", ascending: false)
    fetchOptions.sortDescriptors = [sortDescriptor]
    return fetchOptions
}

func fetchPhotos() {
    print("Fetching Photos")
    let options = assetsFetchOptions()
    let allAssets = PHAsset.fetchAssets(with: .image, options: options)
    
    DispatchQueue.global(qos: . background).async {
        allAssets.enumerateObjects { asset, count, _ in
            let imageManager = PHImageManager.default()
            let targetSize = CGSize(width: 250, height: 250)
            let options = PHImageRequestOptions()
            options.isSynchronous = true
            
            imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: options) { image, info in
                guard let image = image else { return }
                let photo = Photo(uiImage: image)
                DispatchQueue.main.async {
                    self.allPhotos.append(photo)
                }
            }
        }
    }
}
}
Run Code Online (Sandbox Code Playgroud)

这也是我的照片对象的样子。

struct Photo: Identifiable {
let id = UUID()
let uiImage: UIImage
}
Run Code Online (Sandbox Code Playgroud)

我不知道为什么点击手势没有选择正确的项目。我花了几个小时试图找出为什么会发生这种情况。我可能最终会使用 UIImagePickerController 来代替哈哈。

无论如何,如果有人可以将此代码复制并粘贴到 Xcode 的新项目中,并在您的实际设备而不是模拟器上运行它。如果您也遇到这种情况,请告诉我。

我在 iPhone X 上运行它。

yaw*_*eix 21

问题是图像手势超出了您定义的框架,我确信有很多方法可以解决这个问题,但我通过添加contentShape修改器解决了这个问题

请将您的图像代码替换为以下内容

Image(uiImage: photo.uiImage)
.resizable()
.scaledToFill()
.frame(width: UIScreen.main.bounds.width/3, height: UIScreen.main.bounds.width/3)
.clipped()
.contentShape(Path(CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width/3, height: UIScreen.main.bounds.width/3)))
.onTapGesture {
    manager.selectedPhoto = photo
}
Run Code Online (Sandbox Code Playgroud)

contentShape 定义手势的点击区域

  • 你不知道这困扰了我多久,准备使用 ImagePickerController。谢谢 (2认同)