I am trying to figure out if my code is causing the problem or if I should submit a bug report to Apple.
In a new project, I have this code:
ContentView()
import SwiftUI
struct ContentView: View {
@State private var showingImagePicker = false
@State private var inputImage: UIImage?
@State private var image: Image?
var body: some View {
ZStack {
Rectangle()
.fill(Color.secondary)
if image != nil {
image?
.resizable()
.scaledToFit()
} else {
Text("Tap to select a picture")
.foregroundColor(.white)
.font(.headline)
}
}
.onTapGesture {
self.showingImagePicker = true
}
.sheet(isPresented: $showingImagePicker, onDismiss: loadImage){
SystemImagePicker(image: self.$inputImage)
}
}
func loadImage() {
guard let inputImage = inputImage else { return }
image = Image(uiImage: inputImage)
}
}
SystemImagePicker.swift
import SwiftUI
struct SystemImagePicker: UIViewControllerRepresentable {
@Environment(.presentationMode) private var presentationMode
@Binding var image: UIImage?
func makeUIViewController(context: Context) -> PHPickerViewController {
var configuration = PHPickerConfiguration()
configuration.selectionLimit = 1
configuration.filter = .images
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {
}
func makeCoordinator() -> Coordinator {
return Coordinator(parent: self)
}
class Coordinator: NSObject, PHPickerViewControllerDelegate {
let parent: SystemImagePicker
init(parent: SystemImagePicker) {
self.parent = parent
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
for img in results {
guard img.itemProvider.canLoadObject(ofClass: UIImage.self) else { return }
img.itemProvider.loadObject(ofClass: UIImage.self) { image, error in
if let error = error {
print(error)
return
}
guard let image = image as? UIImage else { return }
self.parent.image = image
self.parent.presentationMode.wrappedValue.dismiss()
}
}
}
}
}
But when selecting just one image (as per my code, not selecting and then "changing my mind" and selecting another, different image), I get these leaks when running the memory graph in Xcode.
Is it my code, or is this on Apple?
For what it is worth, the Cancel
button on the imagepicker doesn't work either. So, the user cannot just close the picker sheet, an image MUST be selected to dismiss the sheet.
Further note on old UIImagePickerController
Previously, I've used this code for the old UIImagePickerController
import SwiftUI
struct ImagePicker: UIViewControllerRepresentable {
@Environment(.presentationMode) var presentationMode
@Binding var image: UIImage?
class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
let parent: ImagePicker
init(_ parent: ImagePicker) {
self.parent = parent
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let uiImage = info[.originalImage] as? UIImage {
parent.image = uiImage
}
parent.presentationMode.wrappedValue.dismiss()
}
deinit {
print("deinit")
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
}
}
This also result in leaks from choosing an image, but far fewer of them:
question from:
https://stackoverflow.com/questions/65857468/is-this-the-proper-way-to-use-phpicker-in-swiftui-because-im-getting-a-lot-of 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…