SwiftUI: PHPicker все еще загружается
Я работаю над проектом SwiftUI, используя PHPicker. В настоящее время все работает нормально, за исключением того, что всякий раз, когда я открываю сборщик, я получаю предупреждение
[Picker] Showing picker unavailable UI (reason: still loading) with error: (null)
Похоже, что сборщик не полностью инициализирован, когда он вызывается, и действительно показывает
Loading Photos...
при запуске.
Кто-нибудь знает, как это решить?
Мой код выглядит следующим образом:
...
.toolbar {
ToolbarItem {
Button(action: {
showingImagePicker = true
}) {
Label("Add Image", systemImage: "plus")
}
}
}
.sheet(isPresented: $showingImagePicker) {
ImagePickerRepresentable(
showImagePicker: $showingImagePicker,
onCompletion: complete
)
}
это мой
ImagePickerRepresentable
struct ImagePickerRepresentable: UIViewControllerRepresentable {
// MARK: - Environment Object
@Binding var showImagePicker: Bool
let onCompletion: (UIImage) -> Void
// MARK: - Coordinator Class
final class Coordinator: PHPickerViewControllerDelegate {
private let parent: ImagePickerRepresentable
init(_ parent: ImagePickerRepresentable) {
self.parent = parent
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
parent.showImagePicker = false
// unpack the selected items
let itemProviders = results.map(\.itemProvider)
for itemProvider in itemProviders {
if itemProvider.canLoadObject(ofClass: UIImage.self) {
itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, error in
if let image = image as? UIImage {
self?.parent.onCompletion(image)
}
}
} else {
print("Can't load object")
}
}
}
}
func makeUIViewController(context: Context) -> PHPickerViewController {
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
configuration.filter = .images // filter only to images
configuration.selectionLimit = 3
let controller = PHPickerViewController(configuration: configuration)
controller.delegate = context.coordinator // Use Coordinator for delegation
return controller
}
func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) { }
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
}
Заранее спасибо!
1 ответ
Я проверил ваш код и получил ту же ошибку, но он все еще работает.
Вы можете использовать мою версию сборщика, если хотите (переменная метаданных предназначена только для Firebase):
import Foundation
import SwiftUI
import PhotosUI
struct PHPicker: UIViewControllerRepresentable {
// var didFinishPicking: (_ didSelectItems: Bool) -> Void
@Binding var images: [UIImage]
@Binding var picker: Bool
@Binding var imageData: [Data]
var selectionLimitation: Int {
return 5 - images.count
}
func makeCoordinator() -> Coordinator {
return PHPicker.Coordinator(with: self)
}
func makeUIViewController(context: Context) -> PHPickerViewController {
var config = PHPickerConfiguration()
// can also select videos
config.filter = .images
config.selectionLimit = selectionLimitation
config.preferredAssetRepresentationMode = .current
let picker = PHPickerViewController(configuration: config)
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {
}
class Coordinator: NSObject, PHPickerViewControllerDelegate {
var photoPicker: PHPicker
init(with photoPicker: PHPicker) {
self.photoPicker = photoPicker
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
// photoPicker.didFinishPicking(!results.isEmpty)
// Closing picker
photoPicker.picker.toggle()
for img in results {
if img.itemProvider.canLoadObject(ofClass: UIImage.self) {
img.itemProvider.loadObject(ofClass: UIImage.self) { object, err in
if let image = object as? UIImage {
if let mediaData = image.jpegData(compressionQuality: 0.5) {
DispatchQueue.main.async {
self.photoPicker.images.append(image)
self.photoPicker.imageData.append(mediaData)
}
}
}
}
} else {
// Error loading
print("Cannot be loaded")
}
}
}
}
}
Протестировано с:
import SwiftUI
struct ContentView: View {
@State var showingImagePicker = false
@State var images: [UIImage] = []
@State var imagesData: [Data] = []
var body: some View {
NavigationView {
VStack {
if !images.isEmpty {
ForEach(images, id:\.self) { img in
Image(uiImage: img)
.resizable()
.scaledToFit()
}
}
}
.toolbar {
ToolbarItem {
Button(action: {
showingImagePicker = true
}) {
Label("Add Image", systemImage: "plus")
}
}
}
.sheet(isPresented: $showingImagePicker) {
// ImagePickerRepresentable(
// showImagePicker: $showingImagePicker,
// onCompletion: complete
// )
PHPicker(images: $images, picker: $showingImagePicker, imageData: $imagesData)
}
}
}
}