我正在使用 UIImagePickerController 从 SwiftUI 应用程序中的 camera 或 gallery 选择图像。我将 allowsEditing 设置为 true。将其设置为 true 后,它会显示一个正方形来选择照片,如下所示:
我想选择尺寸的图像(例如width = 150和height = 150)而不是那个square。我可以在 SwiftUI 中做到这一点吗?如果是,我怎样才能实现这一目标?
这是我的代码:
import Foundation
import SwiftUI
public struct ImagePickerView: UIViewControllerRepresentable {
private let sourceType: UIImagePickerController.SourceType
private let onImagePicked: (UIImage) -> Void
@Environment(\.presentationMode) private var presentationMode
public init(sourceType: UIImagePickerController.SourceType, onImagePicked: @escaping (UIImage) -> Void) {
self.sourceType = sourceType
self.onImagePicked = onImagePicked
}
public func makeUIViewController(context: Context) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.sourceType = self.sourceType
picker.delegate = context.coordinator
picker.allowsEditing = true
return picker
}
public func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
public func makeCoordinator() -> Coordinator {
Coordinator(
onDismiss: { self.presentationMode.wrappedValue.dismiss() },
onImagePicked: self.onImagePicked
)
}
final public class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
private let onDismiss: () -> Void
private let onImagePicked: (UIImage) -> Void
init(onDismiss: @escaping () -> Void, onImagePicked: @escaping (UIImage) -> Void) {
self.onDismiss = onDismiss
self.onImagePicked = onImagePicked
}
public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
if let img = info[.editedImage] as? UIImage {
self.onImagePicked(img)
} else if let image = info[.originalImage] as? UIImage {
self.onImagePicked(image)
}
self.onDismiss()
}
public func imagePickerControllerDidCancel(_: UIImagePickerController) {
self.onDismiss()
}
}
}
我尝试过允许编辑,这给了我选择照片的方块,但我需要给定照片的宽度和高度选择。这就是想要的结果:
struct ImagePicker: UIViewControllerRepresentable {
@Environment(\.presentationMode) private var presentationMode
var sourceType: UIImagePickerController.SourceType = .photoLibrary
@Binding var image: UIImage
var selectedImage: (UIImage, URL, CGSize) -> Void
var isApplyingCrop: Bool = false
func makeUIViewController(context: Context) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = false // Disable built-in editing
imagePicker.sourceType = sourceType
imagePicker.delegate = context.coordinator
return imagePicker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate, CropViewControllerDelegate {
var parent: ImagePicker
var isApplyingCrop: Bool {
parent.isApplyingCrop
}
init(_ parent: ImagePicker) {
self.parent = parent
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
guard let originalImage = info[.originalImage] as? UIImage else {
print("No image found")
parent.presentationMode.wrappedValue.dismiss()
return
}
// Proceed to the cropping controller with the selected image
let cropViewController = CropViewController(image: originalImage)
cropViewController.delegate = self
if isApplyingCrop {
cropViewController.customAspectRatio = CGSize(width: 270, height: 350)
}
picker.present(cropViewController, animated: true, completion: nil)
}
// CropViewControllerDelegate methods
func cropViewController(_ cropViewController: CropViewController, didCropToImage croppedImage: UIImage, withRect cropRect: CGRect, angle: Int) {
// Generate unique name and URL for the cropped image
let imageName = UUID().uuidString
let imagePath = getDocumentsDirectory().appendingPathComponent(imageName).appendingPathExtension("jpg")
// Save the cropped image
if let jpegData = croppedImage.jpegData(compressionQuality: 0.8) {
do {
try jpegData.write(to: imagePath)
} catch {
print("Error saving cropped image: \(error.localizedDescription)")
}
}
// Pass cropped image, URL, and crop size to the closure
parent.selectedImage(croppedImage, imagePath, cropRect.size)
parent.image = croppedImage
// Dismiss both CropViewController and UIImagePickerController
cropViewController.dismiss(animated: true) {
self.parent.presentationMode.wrappedValue.dismiss()
}
}
func cropViewControllerDidCancel(_ cropViewController: CropViewController) {
// Dismiss the CropViewController if the user cancels
cropViewController.dismiss(animated: true, completion: nil)
}
// Helper function to get the documents directory path
func getDocumentsDirectory() -> URL {
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
}
}
}
如何工作
.fullScreenCover(isPresented: $showImagePicker) {
if let sourceType = self.sourceType {
ImagePicker(sourceType: sourceType,
image: self.$image,isApplyingCrop:true) { img, url, size in
self.isAnyImageGotPicked = true
self.image = img
self.filePath = url
}
.edgesIgnoringSafeArea(.all)
}
}