首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI:当照片选择器关闭时如何调用函数

SwiftUI:当照片选择器关闭时如何调用函数
EN

Stack Overflow用户
提问于 2022-01-18 21:11:24
回答 1查看 180关注 0票数 0

我使用SwiftUI类中的照片选择器将照片和视频加载到数组中。现在,在选择器中选择这些图像后,我将显示它们。效果很好。

相反,当我单击"Add“按钮并将该数组中的对象上传到Cloudinary进行处理和存储时,我想运行一个函数。我可以通过在选择器之外的一个单独的按钮手动实现这一点,但是对于最好的UX,我认为这个函数应该在选中"Add“按钮时自动运行。

当单击"Add“按钮时,如何运行函数?是否需要检查数组是否为空,是否存在其他条件?

下面是采摘者的照片:

下面是选择代码:

代码语言:javascript
复制
import SwiftUI
import PhotosUI

struct PhotoPicker: UIViewControllerRepresentable {
typealias UIViewControllerType = PHPickerViewController

@ObservedObject var mediaItems: PickedMediaItems
var didFinishPicking: (_ didSelectItems: Bool) -> Void

func makeUIViewController(context: Context) -> PHPickerViewController {
    var config = PHPickerConfiguration()
    config.filter = .any(of: [.images, .videos, .livePhotos])
    config.selectionLimit = 0
    config.preferredAssetRepresentationMode = .current
    
    let controller = PHPickerViewController(configuration: config)
    controller.delegate = context.coordinator
    return controller
}

func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {
    
}


func makeCoordinator() -> Coordinator {
    Coordinator(with: self)
}


class Coordinator: PHPickerViewControllerDelegate {
    var photoPicker: PhotoPicker
    
    init(with photoPicker: PhotoPicker) {
        self.photoPicker = photoPicker
    }
    
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        photoPicker.didFinishPicking(!results.isEmpty)
        
        guard !results.isEmpty else {
            return
        }
        
        for result in results {
            let itemProvider = result.itemProvider
            
            guard let typeIdentifier = itemProvider.registeredTypeIdentifiers.first,
                  let utType = UTType(typeIdentifier)
            else { continue }
            
            if utType.conforms(to: .image) {
                self.getPhoto(from: itemProvider, isLivePhoto: false)
            } else if utType.conforms(to: .movie) {
                self.getVideo(from: itemProvider, typeIdentifier: typeIdentifier)
            } else {
                self.getPhoto(from: itemProvider, isLivePhoto: true)
            }
        }
    }
    
    
    private func getPhoto(from itemProvider: NSItemProvider, isLivePhoto: Bool) {
        let objectType: NSItemProviderReading.Type = !isLivePhoto ? UIImage.self : PHLivePhoto.self
        
        if itemProvider.canLoadObject(ofClass: objectType) {
            itemProvider.loadObject(ofClass: objectType) { object, error in
                if let error = error {
                    print(error.localizedDescription)
                }
                
                if !isLivePhoto {
                    if let image = object as? UIImage {
                        DispatchQueue.main.async {
                            self.photoPicker.mediaItems.append(item: PhotoPickerModel(with: image))
                        }
                    }
                } else {
                    if let livePhoto = object as? PHLivePhoto {
                        DispatchQueue.main.async {
                            self.photoPicker.mediaItems.append(item: PhotoPickerModel(with: livePhoto))
                        }
                    }
                }
            }
        }
    }
    
    
    private func getVideo(from itemProvider: NSItemProvider, typeIdentifier: String) {
        itemProvider.loadFileRepresentation(forTypeIdentifier: typeIdentifier) { url, error in
            if let error = error {
                print(error.localizedDescription)
            }
            
            guard let url = url else { return }
            
            let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
            guard let targetURL = documentsDirectory?.appendingPathComponent(url.lastPathComponent) else { return }
            
            do {
                if FileManager.default.fileExists(atPath: targetURL.path) {
                    try FileManager.default.removeItem(at: targetURL)
                }
                
                try FileManager.default.copyItem(at: url, to: targetURL)
                
                DispatchQueue.main.async {
                    self.photoPicker.mediaItems.append(item: PhotoPickerModel(with: targetURL))
                }
            } catch {
                print(error.localizedDescription)
            }
        }
    }
}
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-21 00:56:29

我将这个类添加到视图中:

代码语言:javascript
复制
class PickerStatus: ObservableObject {
    var status: Bool = false
}

然后将这一行添加到PhotoPicker中:

代码语言:javascript
复制
@ObservedObject var finishedSelection: PickerStatus

然后,在协调员中,我补充说:

代码语言:javascript
复制
for result in results {
                
     self.photoPicker.finishedSelection.status = true

...
}

现在,在我的视图中,我可以设置ObservedObject的实例,将它传递到我的子视图中,包括PhotoPicker,并检查相同的观察对象的值:

代码语言:javascript
复制
@ObservedObject var finishedSelection = PickerStatus()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70762412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档