协调器不适用于 UIViewRepresentable?

Posted

技术标签:

【中文标题】协调器不适用于 UIViewRepresentable?【英文标题】:Coordinator is not working for UIViewRepresentable? 【发布时间】:2021-08-20 04:39:57 【问题描述】:

也许我没有正确理解 UIViewRepresentable,但我认为这会起作用。

我正在尝试使用两个 UIViewRepresentable 类在 SwiftUI 中显示我的 scnkit 场景。我还为这些类使用了两种协调器方法,各一种。协调器可以访问当前场景的渲染和物理世界方法。

玩家在第一个场景中生成,当与敌人接触时,它会过渡到第二个场景。 问题从这里开始,它没有让第二个协调器处理第二个类的物理世界和渲染方法。

我相信这是因为即使场景发生变化,我仍在使用 swiftui 中的第一类而不是第二类。或者换句话说,我正在改变场景而不是正在使用的类。

问题:我怎样才能从第一个场景过渡到第二个场景和/或从第一个场景过渡到另一个场景,并且仍然让协调器为每个场景都处于活动状态。

这是第一堂课。

struct FirstClass : UIViewRepresentable 

    var view = SCNView()
    var scene = SCNScene(named: "First.scn")!

    func makeCoordinator() -> Coordinator 
        Coordinator(self)
    

    func makeUIView(context: Context) -> SCNView 
        scene.physicsWorld.contactDelegate = context.coordinator
        view.delegate = context.coordinator
        return view
    

    ...

    /// Transitions into the second scene.
    func changeScenes() 
        controlManager.jumped = false
        let transition = SKTransition.fade(with: .black, duration: 0.5)
        let secondClass = SecondClass()
         view.present(secondClass.scene, with: transition, incomingPointOfView: nil)
    

这是第二课

struct SecondClass : UIViewRepresentable 

    var view = SCNView()
    var scene = SCNScene(named: "Second.scn")!

    func makeCoordinator() -> SecondCoordinator 
        SecondCoordinator(self)
    

    func makeUIView(context: Context) -> SCNView 
        scene.physicsWorld.contactDelegate = context.coordinator
        view.delegate = context.coordinator
        return view
    

这里是 SwiftUI 类

struct Game: View 

    var view = FirstClass()

    var body: some View 
        ZStack 
            view
            
            ...
        
    

【问题讨论】:

你似乎没有使用SecondClassview属性,你需要第二个SCNView,还是只是为了应付UIViewRepresentable 我将使用它转换回第一个场景。 但我假设你只会使用场景,对吧?视图将保持不变。 我还使用视图/场景将其委托设置为相应的协调器。这样它就会有自己的物理世界和渲染方法。 那么你可能使用了错误的抽象:) 【参考方案1】:

let secondClass = SecondClass() 这部分不起作用,因为 SwiftUI 不知道SecondClass 的实例,以便正确管理其生命周期。此外,您似乎没有使用 SecondClass 结构的 view 属性(顺便说一句,结构的有趣名称:))

一种解决方案是在同一个UIViewRepresentable 中管理两个场景,基本上将生命周期管理保持在同一侧。

struct MyScene : UIViewRepresentable 

    var view = SCNView()
    var firstScene = SCNScene(named: "First.scn")!
    lazy var secondScene = SCNScene(named: "Second.scn")!

    ...

    /// Transitions into the second scene.
    func changeScenes() 
        controlManager.jumped = false
        let transition = SKTransition.fade(with: .black, duration: 0.5)
        view.present(secondScene, with: transition, incomingPointOfView: nil)
    

【讨论】:

如果两个场景使用相同的协调器并且您需要更新 makeUI 方法以包含和设置两个场景,这可能会起作用。您还需要包含来自两个视图的代码来管理场景及其节点(这将很快用大量代码填充结构)。 SecondClass 这个名字是我在例子中使用的名字,不一定是我实际使用的名字。不过,您确实提出了一个公平的观点。 @JamesCastrejon 你可以保留两个协调员,以保持关注点分开,并且只在这个“视图”中进行分配。

以上是关于协调器不适用于 UIViewRepresentable?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 UITableViewAutomaticDimension 不适用于 sectionFooterHeight?

为啥排序不适用于矢量?

验证不适用于 saveMany

UipanGesture 不适用于 Uiswitch

jQuery 不适用于 Express

为啥 MultiBinding 不适用于 CornerRadius