UIImagePickerController 在替换图像几次后崩溃并抛出错误

问题描述 投票:0回答:1

我正在使用 UIImagePickerController 来实现它提供的编辑功能,但我遇到了一个小问题。如果我更换图像几次,大约 5-6 次它就会崩溃并返回如下警告:

<0x100d08660> 手势:系统手势门超时。

[u 0A3027E7-E344-4002-9629:m (null)] [com.apple.mobileslideshow.photo-picker(1.0)] 使用时与插件的连接中断。

[u 0A3027E7-E344-4002-9629:m (null)] [com.apple.mobileslideshow.photo-picker(1.0)] 使用时与插件的连接无效。

-[PUPhotoPickerHostViewController viewServiceDidTerminateWithError:] 错误错误域=_UIViewServiceInterfaceErrorDomain Code=3“(null)”UserInfo={Message=服务连接中断}

-[PUPhotoPickerHostViewController viewServiceDidTerminateWithError:] 错误错误域=_UIViewServiceInterfaceErrorDomain Code=3“(null)”UserInfo={Message=服务连接中断}

-[PUPhotoPickerHostViewController viewServiceDidTerminateWithError:] 错误错误域=_UIViewServiceInterfaceErrorDomain Code=3“(null)”UserInfo={Message=服务连接中断}

这是代码:

import SwiftUI

struct ImagePicker: UIViewControllerRepresentable {
    var sourceType: UIImagePickerController.SourceType = .photoLibrary
    
    @Binding var selectedImage: UIImage
    @Binding var showSheet: Bool
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
        
        let imagePicker = UIImagePickerController()
        imagePicker.allowsEditing = true
        imagePicker.sourceType = sourceType
        imagePicker.delegate = context.coordinator
        
        let appearance = UINavigationBarAppearance()
        appearance.configureWithTransparentBackground()
        appearance.backgroundColor = .systemBackground
        appearance.titleTextAttributes = [.foregroundColor: UIColor.systemBackground]
        appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.systemBackground]
        
        imagePicker.navigationBar.tintColor = .white
        imagePicker.navigationBar.standardAppearance = appearance
        imagePicker.navigationBar.compactAppearance = appearance
        imagePicker.navigationBar.scrollEdgeAppearance = appearance
        
        return imagePicker
    }
    
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
        
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
        
        var parent: ImagePicker
        
        init(_ parent: ImagePicker) {
            self.parent = parent
        }
        
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            
            if let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
                parent.selectedImage = image
            }
            
            parent.showSheet = false
        }
        
    }
}

struct ImagePickerTest: View {
    @State private var image = UIImage()
    @State private var showSheet = false
    
    var body: some View {
        VStack {

            Button("Change photo") {
                showSheet = true
            }
            Image(uiImage: self.image)
                .resizable()
                .frame(width: 100, height: 100)
                .background(Color.gray)
                .scaledToFit()
                .clipShape(Circle())
        }
        .sheet(isPresented: $showSheet) {
            ImagePicker(sourceType: .photoLibrary, selectedImage: $image, showSheet: $showSheet)
                .ignoresSafeArea(.all)
        }
    }
}

不知道从这里去哪里。这是我第一次看到这个。

我使用了 PhotosUI 包中的 PhotosPicker,它从来没有像这样失败过。唯一的缺点是它不提供像 UIImagePickerController 这样的编辑模式。

我想知道在选择图像之后或选择下一张图像之前是否需要进行一些“清理”?

ios swift swiftui uiimagepickercontroller
1个回答
0
投票

虽然我没有遇到过你的代码发生任何崩溃的情况,甚至更改图像 10 次,但我相信你。每次选择新照片时,我仍然看到内存使用量增加。我猜这是内存泄漏。您可以尝试通过压缩正在加载的图像来缓解这种情况。为此,您可以将此属性添加到您的 ImagePicker 结构中:

var size: CGSize = .init(width: 300, height: 300)

这将允许您选择图像的大小。 然后在

imagePickerController
功能中应用实际压缩:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        
        if let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
            parent.selectedImage = image.preparingThumbnail(of: CGSize(width: parent.size.width / 2,
                                                                       height: 300))!
        }
        parent.showSheet = false
    }

此外,您还需要更新主视图以使用 GeometryReader 来提取尺寸:

GeometryReader {
        let size = $0.size
        VStack(alignment: .center) {
            
            Button("Change photo") {
                showSheet = true
            }
            Image(uiImage: self.image)
                .resizable()
                .frame(width: 100, height: 100)
                .background(Color.gray)
                .scaledToFit()
                .clipShape(Circle())
        }
        .sheet(isPresented: $showSheet) {
            ImagePicker(sourceType: .photoLibrary, 
                        selectedImage: $image,
                        showSheet: $showSheet,
                        size: size)
                .ignoresSafeArea(.all)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)

让我知道这对你来说如何工作以及它是否仍然崩溃!

© www.soinside.com 2019 - 2024. All rights reserved.