【问题标题】:Can't Turn UIKit Into Swift UI With UIViewRepresentable无法使用 UIViewRepresentable 在 Swiftui 中打开 UIKit
【发布时间】:2022-08-05 19:12:55
【问题描述】:

我已经关注了两个关于 UIViewRepresentable 的教程,并认为以下内容会起作用,但它没有,我认为我的情况比教程中的情况更复杂。

您好,我正在尝试转此代码

 import SpriteKit
 import AVFoundation

class ViewController: NSViewController {
    
    @IBOutlet var skView: SKView!
    var videoPlayer: AVPlayer!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        if let view = self.skView {
            // Load the SKScene from \'backgroundScene.sks\'
            guard let scene = SKScene(fileNamed: \"backgroundScene\") else {
                print (\"Could not create a background scene\")
                return
            }
            // Set the scale mode to scale to fit the window
            scene.scaleMode = .aspectFill
            // Present the scene
            view.presentScene(scene)
            
            // Add the video node
            guard let alphaMovieURL = Bundle.main.url(forResource: \"camera_city_animated\", withExtension: \"mov\") else {
                print(\"Failed to overlay alpha movie on the background\")
                return
            }
            videoPlayer = AVPlayer(url: alphaMovieURL)
            let video = SKVideoNode(avPlayer: videoPlayer)
            video.size = CGSize(width: view.frame.width, height: view.frame.height)
            print( \"Video size is %f x %f\", video.size.width, video.size.height)
            scene.addChild(video)
            
            // Play video
            videoPlayer.play()
            
            videoPlayer?.actionAtItemEnd = .none

            NotificationCenter.default.addObserver(self,
                                                   selector: #selector(playerItemDidReachEnd(notification:)),
                                                   name: .AVPlayerItemDidPlayToEndTime,
                                                   object: videoPlayer?.currentItem)

            
        }
    }
    @objc func playerItemDidReachEnd(notification: Notification) {
        if let playerItem = notification.object as? AVPlayerItem {
            playerItem.seek(to: CMTime.zero, completionHandler: nil)
        }
    }
}

通过将其放置在我的 struct TransparentVideoLoop: UIViewRepresentable {} 结构的 func makeUIView(context: Context) -> UITextView {} 中,进入 SwiftUI 视图。

我错过了什么?

完整代码:

struct TransparentVideoLoop: UIViewRepresentable {
    func makeUIView(context: Context) -> UITextView {
        @IBOutlet var skView: SKView!
        var videoPlayer: AVPlayer!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            if let view = self.skView {
                // Load the SKScene from \'backgroundScene.sks\'
                guard let scene = SKScene(fileNamed: \"backgroundScene\") else {
                    print (\"Could not create a background scene\")
                    return
                }
                // Set the scale mode to scale to fit the window
                scene.scaleMode = .aspectFill
                // Present the scene
                view.presentScene(scene)
                
                // Add the video node
                guard let alphaMovieURL = Bundle.main.url(forResource: \"camera_city_animated\", withExtension: \"mov\") else {
                    print(\"Failed to overlay alpha movie on the background\")
                    return
                }
                videoPlayer = AVPlayer(url: alphaMovieURL)
                let video = SKVideoNode(avPlayer: videoPlayer)
                video.size = CGSize(width: view.frame.width, height: view.frame.height)
                print( \"Video size is %f x %f\", video.size.width, video.size.height)
                scene.addChild(video)
                
                // Play video
                videoPlayer.play()
                
                videoPlayer?.actionAtItemEnd = .none

                NotificationCenter.default.addObserver(self,
                                                       selector: #selector(playerItemDidReachEnd(notification:)),
                                                       name: .AVPlayerItemDidPlayToEndTime,
                                                       object: videoPlayer?.currentItem)

                
            }
        }
        @objc func playerItemDidReachEnd(notification: Notification) {
            if let playerItem = notification.object as? AVPlayerItem {
                playerItem.seek(to: CMTime.zero, completionHandler: nil)
            }
        }
    }
    

    func updateUIView(_ uiView: UITextView, context: Context) {
       
    }
}

我必须返回视图,但这比教程中的要复杂。

  • 改用UIViewControllerRepresentable 并将整个ViewController 包裹在makeUIViewController 中。

标签: swiftui uiviewrepresentable


【解决方案1】:

请改用UIViewControllerRepresentablehere 是一个基本示例(注意它缺少更新实现),复制如下:

//
//  ImagePicker.swift
//  CoreDataSync
//
import Foundation
import SwiftUI

/// This struct wraps a `UIImagePickerController` for use in SwiftUI.
struct ImagePicker: UIViewControllerRepresentable {
    @Binding var selectedImage: UIImage?
    @Environment(\.presentationMode) var presentationMode

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

    func makeUIViewController(context: Context) -> some UIViewController {
        let imagePickerController = UIImagePickerController()
        imagePickerController.sourceType = .photoLibrary
        imagePickerController.delegate = context.coordinator
        return imagePickerController
    }

    func makeCoordinator() -> ImagePicker.Coordinator {
        Coordinator(parent: self)
    }

    final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
        let parent: ImagePicker

        init(parent: ImagePicker) {
            self.parent = parent
        }

        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
            DispatchQueue.main.async {
                self.parent.selectedImage = (info[.editedImage] ?? info[.originalImage]) as? UIImage
                self.parent.presentationMode.wrappedValue.dismiss()
            }
        }
    }
}

【讨论】: