Official reply in Feedback Assistant: this feature was removed in Xcode 14, and it would not be coming back.
Post
Replies
Boosts
Views
Activity
The delay and memory usage spike you're experiencing are likely due to the process of loading and displaying high-resolution images directly in the SwiftUI view. Each time you pick an image, it's being loaded in its original size which consumes a large amount of memory, especially if you are selecting multiple images. Moreover, the ForEach loop rebuilds each time photosData changes, which also could be causing a delay.
Before appending the image data to photosData, reduce the image resolution to a reasonable size that fits your UI. And load the images in a background thread to prevent UI freezing. In addition, use Lazy Loading: In SwiftUI, you can use LazyHStack instead of HStack to load the images lazily.
For example :
struct ImageTest: View {
@State private var selectedPhotos: [PhotosPickerItem] = []
@State private var photosData: [UIImage] = []
@State private var text: String = ""
var body: some View {
NavigationStack{
Form {
Section {
HStack {
PhotosPicker(selection: $selectedPhotos,
maxSelectionCount: 10,
matching: .images,
photoLibrary: .shared()) {
AddPhotoIcon(numOfImages: photosData.count)
}
.task(id: selectedPhotos) {
for selectedPhoto in selectedPhotos {
if let data = try? await selectedPhoto.loadTransferable(type: Data.self) {
if let image = UIImage(data: data) {
self.photosData.append(image.resized(to: CGSize(width: 50, height: 50))!)
}
}
}
self.selectedPhotos = []
}
if !photosData.isEmpty {
ScrollView(.horizontal) {
LazyHStack {
ForEach(photosData, id: \.self) { image in
Image(uiImage: image)
.resizable()
.scaledToFill()
.frame(width: 50, height: 50)
}
}
}
}
Spacer()
}
}
Section {
TextField("Any", text: $text)
}
}
}
}
}
extension UIImage {
func resized(to size: CGSize) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
self.draw(in: CGRect(origin: .zero, size: size))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}