首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从SwiftUI调用PHPhotoLibrary presentLimitedLibraryPicker?

如何从SwiftUI调用PHPhotoLibrary presentLimitedLibraryPicker?
EN

Stack Overflow用户
提问于 2020-09-13 19:32:19
回答 2查看 2K关注 0票数 3

从SwiftUI调用PHPhotoLibrary的presentLimitedLibraryPicker方法的正确方式是什么?

该方法需要一个我在SwiftUI中没有的UIViewController。

我曾尝试使用UIViewControllerRepresentable来创建一个UIViewController,它可以工作,但结果是出现了两个视图控制器,一个是我用UIViewControllerRepresentable创建的,另一个是有限的库选择器。

为了回到原来的屏幕,两个视图控制器都需要关闭,这是不可取的。

总结一下我看到的问题:

  1. presentLimitedLibraryPicker通过传递ViewController来工作。
  2. 这让我创建并呈现一个虚拟的ViewController,这样我就可以调用该方法了。
  3. 没有办法获得对有限库选择器的引用,而且它也没有提供委托。因此,我无法检测到Limited Library Picker控制器何时被解除。

这是我的尝试(它显示了选择器,但当你关闭它时,你也需要关闭额外的,虚拟的,视图控制器:

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

struct TestView: View {

   @State var showLibraryPicker = false

var body: some View {
    NavigationView {
        VStack {
            Button("Open Library Picker") { showLibraryPicker = true }
        }
        .navigationBarTitle("Test", displayMode: .inline)
        .navigationViewStyle(StackNavigationViewStyle())
        .sheet(isPresented: $showLibraryPicker, onDismiss: { print("Dismissed") }) {
            TestLimitedLibraryPicker()
            }
        }
    }
}


struct TestLimitedLibraryPicker: UIViewControllerRepresentable {

     func makeUIViewController(context: Context) -> UIViewController {
         let controller = UIViewController()
         PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: controller)
          return controller
     }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {

     }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-18 02:37:53

下面是一些演示方法。用Xcode12/ iOS 14编写和测试。

代码语言:javascript
复制
struct TestPhotosView: View {

    @State var showLibraryPicker = false

    var body: some View {
        NavigationView {
            VStack {
                Button("Open Library Picker") { self.showLibraryPicker = true }
            }
            .navigationBarTitle("Test", displayMode: .inline)
            .navigationViewStyle(StackNavigationViewStyle())
            .background(Group {
                if self.showLibraryPicker {
                    TestLimitedLibraryPicker(isPresented: $showLibraryPicker)
                }
            })
        }
    }
}


struct TestLimitedLibraryPicker: UIViewControllerRepresentable {
    @Binding var isPresented: Bool

    func makeUIViewController(context: Context) -> UIViewController {
        let controller = UIViewController()

        DispatchQueue.main.async {
            PHPhotoLibrary.requestAuthorization() { result in
                PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: controller)
                context.coordinator.trackCompletion(in: controller)
            }
        }
        
        return controller
    }

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

    func makeCoordinator() -> Coordinator {
        Coordinator(isPresented: $isPresented)
    }
    class Coordinator: NSObject {
        private var isPresented: Binding
        init(isPresented: Binding) {
            self.isPresented = isPresented
        }

        func trackCompletion(in controller: UIViewController) {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self, weak controller] in
                if controller?.presentedViewController == nil {
                    self?.isPresented.wrappedValue = false
                } else if let controller = controller {
                    self?.trackCompletion(in: controller)
                }
            }
        }
    }
}
票数 5
EN

Stack Overflow用户

发布于 2021-02-26 05:51:18

刚遇到这个问题!这是我的观点。

  • 没有SwiftUI方法来调用有限的照片选择器。所以我们必须创建一个视图控制器(UIViewControllerRepresentable)哪个调用.presentLimitedLibraryPicker..。但是如果您将其表示为工作表,它将立即显示选取器,并且您将在工作表上获得工作表。
  • 相反,应该嵌入包装的视图控制器直接在视图的主体中并将其绑定传递给触发器条件。
  • 在包装的视图控制器中,查找对中的条件的更改updateUIViewController..。如果值为true,显示选取器,然后立即关闭该值。
代码语言:javascript
复制
import SwiftUI
import UIKit
import PhotosUI

struct ContainingView: View {
    @State var showLimitedPicker: Bool = false

    var body: some View {
        HStack {
            Button("Load more…") { showLimitedPicker = true }
            LimitedPicker(isPresented: $showLimitedPicker)
                .frame(width: 0, height: 0)
        }
    }
}

struct LimitedPicker: UIViewControllerRepresentable {
    @Binding var isPresented: Bool

    func makeUIViewController(context: Context) -> UIViewController {
        UIViewController()
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
        if isPresented {
            PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: uiViewController)
            DispatchQueue.main.async {
                isPresented = false
            }
        }
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63870238

复制
相关文章

相似问题

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