Photos Picker Selection

Hi! I am having a bit of trouble with the Photos Picker. In my app, users are able to select photos to appear in a grid, right in the app. I am using the new Photos Picker with SwiftUI. I want to be able to have my users select the images after they have been added to the View. So I want there to be a select button in the top toolbar on the leading side, and then once the user hits the select button, they can select the photos they want to remove on the grid, just like in the photos app, and then where the button to add photos originally is, there will be a trash icon to remove the selected photos from the grid.

How would I do this? I have attached my code below for my view, as well as my PhotoPicker:

import PhotosUI

struct LifestyleImagePicker: View {
    @StateObject var imagePicker = ImagePicker()
    @State private var showingDetail = false
    @State private var selectedIndex = 0
    @State private var isSelecting = false
    @State private var isAddingPhoto = false
    
    let columns = [GridItem(.adaptive(minimum: 100))]
    
    var body: some View {
        NavigationSplitView {
            VStack {                    
                if !imagePicker.images.isEmpty {
                    ScrollView {
                        LazyVGrid(columns: columns, spacing: 3) {
                            ForEach(imagePicker.images.indices, id: \.self) { index in
                                imagePicker.images[index]
                                    .resizable()
                                    .scaledToFit()
                                    .onTapGesture {
                                        selectedIndex = index
                                        showingDetail = true
                                    }
                            }
                        }
                    }
                } else {
                    Text("Tap the plus icon to add photos to your own Inspo Board.")
                        .multilineTextAlignment(.center)
                }
                
            }
            .padding()
            .navigationTitle("Lifestyle")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    PhotosPicker(selection: $imagePicker.imageSelections,
                                 maxSelectionCount: 10,
                                 matching: .images,
                                 photoLibrary: .shared()) {
                        Image(systemName: "photo.badge.plus")
                            .imageScale(.large)
                    }
                }
            }
        } detail: {
            Text("Pick your lifestyle")
        }
            
            .sheet(isPresented: $showingDetail) {
                DetailImageView(images: $imagePicker.images, selectedIndex: selectedIndex)
            }
        }
    }

#Preview {
    LifestyleImagePicker()
}

import PhotosUI
import Combine
import Foundation

@MainActor
class ImagePicker: ObservableObject {
    @Published var image: Image?
    @Published var images: [Image] = []
    @Published var imageSelection: PhotosPickerItem? {
        didSet {
            if let imageSelection {
                Task {
                    try await loadTransferable(from: imageSelection)
                }
            }
        }
    }
    @Published var imageSelections: [PhotosPickerItem] = [] {
        didSet {
            Task {
                if !imageSelections.isEmpty {
                    try await loadTransferable(from: imageSelections)
                    imageSelections = []
                }
            }
        }
    }

    func loadTransferable(from imageSelections: [PhotosPickerItem]) async throws {
        do {
            for imageSelection in imageSelections {
                if let data = try await imageSelection.loadTransferable(type: Data.self) {
                    if let uiImage = UIImage(data: data) {
                        self.images.append(Image(uiImage: uiImage))
                    }
                }
            }
        } catch {
            print(error.localizedDescription)
        }
    }

    func loadTransferable(from imageSelection: PhotosPickerItem?) async throws {
        do {
            if let data = try await imageSelection?.loadTransferable(type: Data.self) {
                if let uiImage = UIImage(data: data) {
                    self.image = Image(uiImage: uiImage)
                }
            }
        } catch {
            print(error.localizedDescription)
            image = nil
        }
    }
}

Could you please elaborate what issues you are seeing when using the PhotosPicker API?

If you want to present the picker programmatically, you can also use the .photosPicker(isPresented:) modifier instead of the PhotosPicker view, where the former gives you a Bool binding to control the presentation and dismissal of the picker UI.

Photos Picker Selection
 
 
Q