I have an app that uses a Photospicker to allow the user to select photos and view them in a PhotosView: this is the viewModel for selecting the photos:
@MainActor
@Observable
final class PhotosPickerViewModel {
var selectedImages: [UIImage] = []
var imageSelections: [PhotosPickerItem] = [] { //temporary Photoitems the user selects
didSet {
setImages(from: imageSelections) //when it changes convert those items into imageSelections
}
}
//Turn the PhotosPickerItem into a UIimage we can use in views
private func setImages(from selections: [PhotosPickerItem]) {
Task {
var images: [UIImage] = []
for selection in selections {
if let data = try? await selection.loadTransferable(type: Data.self) {
if let uiImage = UIImage(data: data) {
images.append(uiImage)
}
}
}
selectedImages = images
}
}
}
And in my main View I have a navigationStack with a NavigationPath and to navigate back I clear both the path and the imageSelections:
//View that Contains the PhotosPicker
BottomToolbar(selectedItems: $photosPickerViewModel.imageSelections)
.padding(.bottom, bottomPadding)
.padding(.top, 40)
.onChange(of: photosPickerViewModel.selectedImages) { oldValue, newValue in
if !newValue.isEmpty {
path = NavigationPath() //clear the old path
path.append(newValue) //append the new value
}
}
.navigationDestination(for: [UIImage].self) { images in
PhotosView(selectedImages: images) {
photosPickerViewModel.selectedImages.removeAll()
photosPickerViewModel.imageSelections.removeAll()
path.removeLast()
}
}
This does clear the path and return me to the root of the NavigationStack but the image selections remain despite me removing them, and even worse when I go into PhotosPicker where the old selections remain the add button doesnt trigger navigation (you have to add at least one photo for navigation to work properly again)
I have an app that uses a Photospicker to allow the user to select photos and view them in a PhotosView: this is the viewModel for selecting the photos:
@MainActor
@Observable
final class PhotosPickerViewModel {
var selectedImages: [UIImage] = []
var imageSelections: [PhotosPickerItem] = [] { //temporary Photoitems the user selects
didSet {
setImages(from: imageSelections) //when it changes convert those items into imageSelections
}
}
//Turn the PhotosPickerItem into a UIimage we can use in views
private func setImages(from selections: [PhotosPickerItem]) {
Task {
var images: [UIImage] = []
for selection in selections {
if let data = try? await selection.loadTransferable(type: Data.self) {
if let uiImage = UIImage(data: data) {
images.append(uiImage)
}
}
}
selectedImages = images
}
}
}
And in my main View I have a navigationStack with a NavigationPath and to navigate back I clear both the path and the imageSelections:
//View that Contains the PhotosPicker
BottomToolbar(selectedItems: $photosPickerViewModel.imageSelections)
.padding(.bottom, bottomPadding)
.padding(.top, 40)
.onChange(of: photosPickerViewModel.selectedImages) { oldValue, newValue in
if !newValue.isEmpty {
path = NavigationPath() //clear the old path
path.append(newValue) //append the new value
}
}
.navigationDestination(for: [UIImage].self) { images in
PhotosView(selectedImages: images) {
photosPickerViewModel.selectedImages.removeAll()
photosPickerViewModel.imageSelections.removeAll()
path.removeLast()
}
}
This does clear the path and return me to the root of the NavigationStack but the image selections remain despite me removing them, and even worse when I go into PhotosPicker where the old selections remain the add button doesnt trigger navigation (you have to add at least one photo for navigation to work properly again)
Share Improve this question edited Mar 17 at 15:07 john smith asked Mar 17 at 13:51 john smithjohn smith 1516 bronze badges 1 |1 Answer
Reset to default 0You can simply empty out the Photopickeritems once you have converted them to Images:
var imageSelections: [PhotosPickerItem] = [] { //temporary Photoitems the user selects
didSet {
setImages(from: imageSelections) //when it changes convert those items into imageSelections
}
}
//Turn the PhotosPickerItem into a UIimage we can use in views
private func setImages(from selections: [PhotosPickerItem]) {
Task {
var images: [UIImage] = []
for selection in selections {
if let data = try? await selection.loadTransferable(type: Data.self) {
if let uiImage = UIImage(data: data) {
images.append(uiImage)
}
}
}
selectedImages = images
imageSelections.removeAll()
}
}
PhotosPickerViewModel
with@State
and.task(id: selections)
it's best to encapsulate your view data in the View model struct hierarchy. – malhal Commented Mar 17 at 16:21