微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有UIViewControllerRepresentable

如何解决带有UIViewControllerRepresentable

我正在尝试在swiftUi项目中使用可表示的UIViewController。具体来说,我尝试按下一个按钮(assetone),该按钮允许EU选择视频,然后按下另一个按钮(assetTwo),它允许用户选择另一个视频。然后,用户可以选择合并视频(带有第三个按钮)。我以为我需要使用协调器来完成此操作,但是在看到SO solution without it之后,我尝试了不带协调器的情况。但是,当我运行我的项目时,构建成功,但是当我从内容视图中单击任何按钮时,都会收到以下错误消息。我究竟做错了什么?我需要协调器吗,如何将其与当前配置结合?

警告:尝试显示上,其视图是 不在窗口层次中!

内容视图:

import SwiftUI

struct ContentView: View {
    
    let someView = ImagePicker()
    
    var body: some View {
        vstack {
            Button(action: {
                print("SwiftUI: assetone button tapped")
                // Call func in SomeView()
                self.someView.assetone()
            }) {
                Text("Asset One").foregroundColor(Color.black)
            }
            .background(Color.blue)
            .padding(10)
            .clipShape(Capsule())
}
//...

图像选择器:UIViewControllerRepresentable

struct ImagePicker: UIViewControllerRepresentable{
    
    let someView = MergeVideoViewController()

func makeUIViewController(context: Context) -> MergeVideoViewController {
      someView
    }

    func updateUIViewController(_ uiViewController: MergeVideoViewController,context: Context) {}
    
    func assetone() {
        someView.loadAssetone()
    }
    //...
}

我的UIViewController类:

class MergeVideoViewController: UIViewController {
    var firstAsset: AVAsset?
    var secondAsset: AVAsset?
    var audioAsset: AVAsset?
    var loadingAssetone = false
    var activityMonitor: UIActivityIndicatorView!
    
func exportDidFinish(_ session: AVAssetExportSession) {
    // Cleanup assets
    activityMonitor.stopAnimating()
    firstAsset = nil
    secondAsset = nil
    audioAsset = nil

//...

func loadAssetone() {
        //  func loadAssetone(_ sender: AnyObject) {
        if savedPhotosAvailable() {
            loadingAssetone = true
            VideoHelper.startMediabrowser(delegate: self,sourceType: .savedPhotosAlbum)
        }
    }

//...

解决方法

ImagePicker是一个视图,它应该位于body中。

这是一种可能的方法-想法是在SwiftUI中获取控制器引用,并在需要时直接调用其操作。

struct ImagePicker: UIViewControllerRepresentable{
    let configure: (MergeVideoViewController) -> ()

    func makeUIViewController(context: Context) -> MergeVideoViewController {
       let someView = MergeVideoViewController()
       configure(someView)
       return someView
    }

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

struct ContentView: View {

    @State private var controller: MergeVideoViewController?

    var body: some View {
        VStack {
            ImagePicker {
                self.controller = $0
            }

            Button(action: {
                print("SwiftUI: assetOne button tapped")
                self.controller?.loadAssetOne()
            }) {
                Text("Asset One").foregroundColor(Color.black)
            }
            .background(Color.blue)
            .padding(10)
            .clipShape(Capsule())
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。