我正在使用 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 这样的编辑模式。
我想知道在选择图像之后或选择下一张图像之前是否需要进行一些“清理”?
虽然我没有遇到过你的代码发生任何崩溃的情况,甚至更改图像 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)
让我知道这对你来说如何工作以及它是否仍然崩溃!