我正在尝试PHPickerViewController使用 SwiftUI 和可组合架构来实现。(并不是说我认为这特别相关,但它可以解释为什么我的一些代码是这样的)。
我一直在尝试解决这个问题。我在 GitHub 上创建了一个小示例项目,它删除了可组合架构并保持 UI 超级简单。
https://github.com/oliverfoggin/BrokenImagePickers/tree/main
看起来 iOS 15 在 UIImagePickerViewController 和 PHPickerViewController 上都出现了问题。(这是有道理的,因为它们都在后台使用相同的 UI)。
我猜接下来的步骤是确定在 UIKit 应用程序中使用它们时是否会发生相同的错误。
我的代码相当简单。它几乎只是使用相同功能的重新实现UIImagePickerViewController,但我想尝试使用较新的 API。
我的代码看起来像这样......
public struct ImagePicker: UIViewControllerRepresentable {
// Vars and setup stuff...
@Environment(\.presentationMode) var presentationMode
let viewStore: ViewStore<ImagePickerState, ImagePickerAction>
public init(store: Store<ImagePickerState, ImagePickerAction>) {
self.viewStore = ViewStore(store)
}
// UIViewControllerRepresentable required functions
public func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> some UIViewController {
// Configuring the PHPickerViewController
var config = PHPickerConfiguration()
config.filter = PHPickerFilter.images
let …Run Code Online (Sandbox Code Playgroud) 我在 iOS 14 上使用新的 PHPicker 时遇到问题。当我的应用程序请求照片库授权时,系统将提示用户三个选项,如果用户选择“选择照片”,系统将呈现一个 PHPicker,其中用户可以选择我的应用程序可以访问的照片和视频。
但现在PHPicker系统的导航栏看起来太糟糕了,它有黑色的背景和黑色的文本颜色(见下面的链接)。我想知道如何定制它的外观。
非常感谢任何回复!
我查看了WWDC2020 视频,该视频解释了如何采用新的 PHPickerViewController API。我还看到几个博客准确地显示了以下代码。
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
if let result = results.first, result.itemProvider.canLoadObject(ofClass: UIImage.self) {
result.itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in
DispatchQueue.main.async {
self.parent.didCapture(image)
}
}
} else {
parent.didCapture(nil)
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这对我来说失败了,而且错误非常奇怪。
UIImage 必须确认 _ObjectiveCBridgable
我将附上屏幕截图,因为它令人难以置信
硬件:M1芯片组
IDE:Xcode 12.4
在 iOS 14 中,Apple 引入了PHPickerViewController 用户有权访问所有照片库视频或选定视频的权限。在第一种情况下,当我们向所有视频提供权限时,我们能够从照片库中获取视频并将其转换为视频数据以将其发送到后端服务器。
但在第二种情况下,当用户向选定的视频提供权限时,在这种情况下,我们可以从照片库中获取视频,但无法将其转换为本地视频 url 中的数据。此时数据始终为零。
我们使用下面的代码从照片库 url 检索视频并将其转换为数据。
// MARK: PHPickerViewControllerDelegate Methods
extension PhotoPickerVC: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
// Always dismiss the picker first
dismiss(animated: true)
if !results.isEmpty {
guard let itemProvider = results.first?.itemProvider else { return }
itemProvider.loadItem(forTypeIdentifier: "public.movie", options: nil) { [weak self] (fileURL, _) in
DispatchQueue.main.async {
guard let videoURL = fileURL as? URL, let _ = self else { return }
do {
//mediaURL video …Run Code Online (Sandbox Code Playgroud) 当我尝试使用 PHPickerViewController 导入图像时收到此消息:
\n\n\n2022-10-29 12:52:17.775185 + 0200 screenfreeze [38500:5423936] [声明] 2AA2E9DE-9603-4723-B04C-35F09BB99667 grantAccessClaim回复是一个错误:错误域= NSCocoaErrorDomain代码= 4101“Couldn \ xe2 \ x 80\ x99t 与辅助应用程序通信。” UserInfo={NSUnderlyingError=0x600000f20330 {Error Domain=PHAssetExportRequestErrorDomain Code=0 “操作无法完成\xe2\x80\x99。(PHAssetExportRequestErrorDomain 错误 0。)” UserInfo={NSLocalizedDescription=操作无法\xe2\x80\x99 完成。(PHAssetExportRequestErrorDomain 错误 0。),NSUnderlyingError=0x600000f20300 {Error Domain=PAMediaConversionServiceErrorDomain Code=2“操作无法\xe2\x80\x99t 完成。(PAMediaConversionServiceErrorDomain 错误 2。)” UserInfo={NSLocalizedDescription=操作无法\xe2\x80 \x99t 完成。(PAMediaConversionServiceErrorDomain 错误 2。)}}}}}
\n
造成这种情况的原因是什么以及如何避免?
\n为了获取照片的创建日期,所以在显示 PHPickerViewController 之前使用 requestAuthorizationForAccessLevel。
PHAccessLevel level = PHAccessLevelReadWrite;
[PHPhotoLibrary requestAuthorizationForAccessLevel:level handler:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusLimited || status == PHAuthorizationStatusAuthorized) {
dispatch_async(dispatch_get_main_queue(), ^{
PHPickerConfiguration *configuration = [[PHPickerConfiguration alloc] initWithPhotoLibrary:[PHPhotoLibrary sharedPhotoLibrary]];
configuration.filter = [PHPickerFilter imagesFilter];
configuration.selectionLimit = 1;
PHPickerViewController *picker = [[PHPickerViewController alloc] initWithConfiguration:configuration];
picker.delegate = self;
[self showViewController:picker sender:nil];
});
}
}];
Run Code Online (Sandbox Code Playgroud)
尽管状态为 .limited,但 iOS 14 仍然显示所有图像。
如何使用 PHPickerViewController 只获取有限的照片?
有没有办法在手动呈现时显示用户当前的照片选择PHPickerViewController?例如,使用以下代码时,选择器不会显示用户当前选择的任何照片。
var pickerConfig = PHPickerConfiguration()
pickerConfig.selectionLimit = 0
pickerConfig.filter = .any(of: [.images])
let imagePicker = PHPickerViewController(configuration: pickerConfig)
imagePicker.delegate = self
// When presented, the user's current selected photos are empty, nothing is selected
viewController.present(imagePicker, animated: true)
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用苹果的内置presentLimitedLibraryPicker功能,它确实会显示用户当前的照片选择:
// This does show the user's current selections
PHPhotoLibrary.shared().presentLimitedLibraryPicker(from controller: self)
Run Code Online (Sandbox Code Playgroud)
有没有办法在不使用的情况下获得这种行为presentLimitedLibraryPicker?
我使用有限照片库功能并选择了一些照片,但是当使用PHPickerViewController在应用程序中选择图像时,PHPickerViewController 会显示图库中的所有图像,而不是之前仅显示一些选定的图像。
是否可以在 PHPickerViewController 中只显示预先选择的图像?如果没有,如何显示预先选择的图像列表,以便用户可以选择之前的 UIImagePickerController。
感谢大家的分享和评论
我一直在尝试在新应用程序中实现照片选择功能。我当前的方法是使用嵌入 UIViewControllerRepresentable 中的 PHPickerViewController 来显示在 swiftUI 视图中。
这是我的 makeUIViewController 函数。
func makeUIViewController(context: Context) -> PHPickerViewController {
var configuration = PHPickerConfiguration()
configuration.filter = filter
configuration.selectionLimit = limit
let controller = PHPickerViewController(configuration: configuration)
controller.delegate = context.coordinator
return controller
}
Run Code Online (Sandbox Code Playgroud)
它位于名为的结构内PhotoPicker:
struct PhotoPicker: UIViewControllerRepresentable {
Run Code Online (Sandbox Code Playgroud)
是的,所有这些。让我解释一下,PickerView总是显示的,它不是弹出窗口,因此不需要取消按钮。正如您所看到的,也没有完成按钮。这是因为只需要选择一张图像,所以当用户点击图像时,会立即调用选择新图像的事件。无需用户确认。然后关于搜索栏,我并不是真的想要它,我只是希望用户选择一张照片,最后照片和相册之间的小切换在我的情况下也不是真正必要的。
我尝试了很多不同的方法,包括尝试在makeUIViewController. 这些选项例如:
controller.navigationController?.setToolbarHidden(true, animated: false)
controller.navigationController?.setNavigationBarHidden(true, animated: false)
Run Code Online (Sandbox Code Playgroud)
我还尝试在 SwiftUI 主体中调用视图修饰符:
PhotoPicker(filter: .images, limit: 1) { (results) in
}
.navigationBarTitle("")
.navigationBarHidden(true)
.statusBar(hidden: true)
.navigationBarBackButtonHidden(true)
Run Code Online (Sandbox Code Playgroud)
但同样,它们似乎都不起作用。所以这就是我在这里问的原因,因为似乎我尝试了一切,但没有任何效果......
在WWDC20 中,苹果引入了PHPicker - UIImagePickerController 的现代替代品。
我想知道是否可以使用新的照片选择器检索 PHAsset?
这是我的代码:
private func presentPicker(filter: PHPickerFilter) {
var configuration = PHPickerConfiguration()
configuration.filter = filter
configuration.selectionLimit = 0
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
present(picker, animated: true)
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
dismiss(animated: true)
}
Run Code Online (Sandbox Code Playgroud)