SKView集成到UIViewController中,UITextFields滞后

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SKView集成到UIViewController中,UITextFields滞后相关的知识,希望对你有一定的参考价值。

我想在我的登录界面中使用SKView来制作一些动画。 SKView作为子视图添加到LoginContainerView以及包含UITextFields和登录按钮的视图中。所有的子视图都使用自动布局定位,并且附加到FireSceneSKView将其scaleMode设置为.resizeFill

从这个片段中我可以清楚地看到我遇到的问题:https://streamable.com/5it17

剪辑说明:每当我双击任何UITextFields(触发UIMenuController / Paste按钮)时,FireScene会冻结很短的时间(但它非常明显)并且FPS会下降到30左右,持续1-2秒。

FireScene添加为其子节点的唯一节点是修改后的萤火虫SKEmitterNode模板。我相当确定这与实际代码无关(因为它非常直接和简洁)并且可能是与SpriteKit混合的UIKit。

相关代码:

class FireScene: SKScene {

    // MARK: - Properties
    var fireSparkEmitter: SKEmitterNode? = nil

    // MARK: - Inherited
    override func didChangeSize(_ oldSize: CGSize) {
        // position the emitter to scene's center
        fireSparkEmitter?.position = CGPoint(x: size.width/2, y: size.height/2)
    }

    override func didMove(to view: SKView) {
        if let emitter = fireSparkEmitter {
            emitter.resetSimulation()
        } else {
            guard let emitter = SKEmitterNode(fileNamed: "FireSparks.sks") else { return }
            addChild(emitter)
            fireSparkEmitter = emitter
        }

    }
}

class LoginContainerView: UIView {
    /// ...
    let fireBackgroundScene: FireScene = {
        let scene = FireScene(size: .zero)
        scene.scaleMode = .resizeFill
        return scene
    }()
    /// ...

    // MARK: - Inherited
    // called after view initialization
   func setupSubviews() {
        let skView = SKView(frame: .zero)
        skView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(skView)
        skView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
        skView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        skView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        skView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true

        skView.showsFPS = true
        skView.presentScene(fireBackgroundScene)
    }
}

PS:我试图用Time Profiler配置应用程序,似乎瓶颈是UIKit本身处理的UITextField手势。

答案

您的问题似乎与SKView和其他UIKit对象之间的不同布局同步有关。 SKView有一个名为isAsynchronous(default = true)的属性,指示内容是否异步呈现。您可以尝试设置:

skView.isAsynchronous = false

SKView与核心动画更新同步。这可能还不够,因为你将SKView与项目的核心动画同步,但总有UIKit风格的动画可能不同步。如果此属性无法解决您的问题,您还可以更改preferredFramesPerSecond属性。请记住,当你尝试混合两个框架(sprite-kitUIKit)时,你将不可避免地招致不愉快的故障。

以上是关于SKView集成到UIViewController中,UITextFields滞后的主要内容,如果未能解决你的问题,请参考以下文章

iOS:UIView 与 SKView

如何从 SKView 转换到 SCNView?

从 UIViewController 移动到 SKcene

SpriteKit:为什么SKView在一个高度消失但出现在另一个高度? SKView的最大高度是多少?

将 SpriteKit 视图集成到 xib 视图中

以编程方式创建 ViewController 时,如何将其视图设置为 SKVIew 类型?