Проблемы с производительностью после использования UIImagePickerController

У меня есть приложение SwiftUI, использующее средство выбора изображений, завернутое в UIViewControllerRepresentable используя .sheet модификатор для его отображения.

После выбора изображения остальная часть приложения более или менее останавливается, пока не произойдет какой-то сбой в фоновом режиме, и все снова не станет быстрым - дополнительная информация после кода:

import SwiftUI

struct StylePanel: View {
    
    @Binding var image: Image?

    @State var inputImage: UIImage? = nil
    @State var showImagePicker: Bool

    func loadImage() {
        guard let inputImage = inputImage else { return }
        image = Image(uiImage: inputImage)
    }
    
    var body: some View {
        
        VStack {
            // Rest of view not shown


            Button(action: {
                self.showImagePicker = true
            }, label: {
                Text("Choose image...")
            })
        }
        .sheet(isPresented: self.$showImagePicker, onDismiss: loadImage){
            ImagePicker(image: self.$inputImage)
        }
    }
}

ImagePicker.swift:

import SwiftUI

struct ImagePicker: UIViewControllerRepresentable {
    @Environment(\.presentationMode) var presentationMode
    @Binding var image: UIImage?

    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        return picker
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {

    }
        
    func makeCoordinator() -> ImagePickerCoordinator {
        return ImagePickerCoordinator(self)
    }
}


class ImagePickerCoordinator: 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()
    }
}

После того, как изображение выбрано, оно отлично отображается в родительском элементе, но другие действия, такие как перетаскивание или изменение состояния, действительно неудобны. Приложение очень не отвечает, пока в конце концов не произойдет что-то странное - есть какой-то viewServiceDidTerminateWithErrorсбой в фоновом режиме и все снова начинает работать отлично, производительность возвращается в норму. Последующие перезагрузки средства выбора изображений только усугубляют ситуацию, пока не произойдет то же самое - сбой в фоновом режиме с последующей нормальной производительностью.

Это ошибка, после которой производительность возвращается в норму:

[ServicesDaemonManager] interruptionHandler is called. -[FontServicesDaemonManager connection]_block_invoke
[xpc] XPC error talking to pkd: Connection interrupted
[lifecycle] [u 123223B6-8A6C-4BC3-9908-269FA8A8B9E6:m (null)] [com.apple.mobileslideshow.photo-picker(1.0)] Connection to plugin interrupted while in use.
[lifecycle] [u 123223B6-8A6C-4BC3-9908-269FA8A8B9E6:m (null)] [com.apple.mobileslideshow.photo-picker(1.0)] Connection to plugin invalidated while in use.
viewServiceDidTerminateWithError:: Error Domain=_UIViewServiceInterfaceErrorDomain Code=3 "(null)" UserInfo={Message=Service Connection Interrupted}
[Generic] -[PUPhotoPickerHostViewController viewServiceDidTerminateWithError:] Error Error Domain=_UIViewServiceInterfaceErrorDomain Code=3 "(null)" UserInfo={Message=Service Connection Interrupted}

Похоже, это напрямую связано с использованием .sheet. Когда я помещаю Picker непосредственно в содержащее представление, он работает нормально без каких-либо проблем.

Я хотел бы знать, как правильно утилизировать UIImagePickerController modal правильно, чтобы устранить эту проблему с производительностью.

Кто-нибудь еще испытал это или знает решение?

1 ответ

Вы пробовали использовать @StateObject var inputImage вместо @State? Это инициализирует изображение один раз, избегая постоянной перезагрузки изображения при изменении вида.

Другие вопросы по тегам