动画的替代品(forKey :)(现已弃用)?

时间:2017-09-01 23:17:09

标签: ios swift scenekit ios11

我正在使用iOS 11(适用于SceneKit),虽然许多人指出来自Apple的extension CAAnimation { class func animationWithSceneNamed(_ name: String) -> CAAnimation? { var animation: CAAnimation? if let scene = SCNScene(named: name) { scene.rootNode.enumerateChildNodes({ (child, stop) in if child.animationKeys.count > 0 { animation = child.animation(forKey: child.animationKeys.first!) stop.initialize(to: true) } }) } return animation } } 示例应用程序使用Fox,但我在该示例项目中使用的扩展程序存在问题(file)添加动画:

SceneKit

似乎这个扩展非常方便,但我不确定如何迁移它现在它已被弃用?现在默认情况下它会内置到<!doctype html> <html> <head> <meta charset="UTF-8"> <title>Classement TOP 10</title> <script src="https://www.gstatic.com/firebasejs/4.2.0/firebase.js"></script> <script> (function(){ // Initialize Firebase var config = { databaseURL: "https://XXXXXXXX.firebaseio.com" }; firebase.initializeApp(config); var userDataRef = firebase.database().ref("users").orderByChild('points').limitToLast(10); userDataRef.once("value") .then(function(snapshot) { snapshot.forEach(function(childSnapshot) { var firstName_val = childSnapshot.val().firstName; // console.log(firstName_val); var lastName_val = childSnapshot.val().lastName.substr(0,1); // console.log(lastName_val); var points_val = childSnapshot.val().points; // console.log(points_val); var x = document.createElement("li"); var t = document.createTextNode(firstName_val + " " + lastName_val + ". - " + points_val + " points"); x.appendChild(t); document.getElementById("classement").appendChild(x); }); }); }()); </script> </head> <body> <div> <ol id="classement"></ol> </div> </body> </html> 吗?

该文档并未真正显示有关其被弃用的原因或从何处开始的详细信息。

由于

2 个答案:

答案 0 :(得分:7)

TL; DR :有关如何使用新API的示例,请参阅Apple sample game(搜索SCNAnimationPlayer

尽管在animation(forKey:)中已弃用CAAnimation及其与iOS11一起使用的姐妹方法,但您可以继续使用它们 - 一切都会有效。

但是如果你想使用新的API并且不关心向后兼容性(无论如何你都不需要ARKit,因为它只能在以后使用iOS11),请继续阅读。

与其前身相比,新推出的SCNAnimationPlayer提供了更方便的API。现在可以更轻松地实时处理动画。 来自WWDC2017的{​​{3}}将是了解它的一个很好的起点。

快速摘要:SCNAnimationPlayer可让您动态更改动画的速度。与添加和删除play()相比,它使用stop()CAAnimation等方法为动画播放提供了更直观的界面。 您还可以将两个动画混合在一起,例如,可以使用它们在它们之间进行平滑过渡。

您可以在This video中找到如何使用所有这些内容的示例。

以下是您发布的适用于SCNAnimationPlayer的扩展程序(您可以在Fox 2示例项目的Character课程中找到):

extension SCNAnimationPlayer {
    class func loadAnimation(fromSceneNamed sceneName: String) -> SCNAnimationPlayer {
        let scene = SCNScene( named: sceneName )!
        // find top level animation
        var animationPlayer: SCNAnimationPlayer! = nil
        scene.rootNode.enumerateChildNodes { (child, stop) in
            if !child.animationKeys.isEmpty {
                animationPlayer = child.animationPlayer(forKey: child.animationKeys[0])
                stop.pointee = true
            }
        }
        return animationPlayer
    }
}

您可以按如下方式使用它:

  1. 加载动画并将其添加到相应的节点

    let jumpAnimation = SCNAnimationPlayer.loadAnimation(fromSceneNamed: "jump.scn")
    jumpAnimation.stop() // stop it for now so that we can use it later when it's appropriate 
    model.addAnimationPlayer(jumpAnimation, forKey: "jump")
    
  2. 使用它!

    model.animationPlayer(forKey: "jump")?.play()
    

答案 1 :(得分:0)

这是 SwiftUI和SceneKit

的示例
import SwiftUI
import SceneKit

struct ScenekitView : UIViewRepresentable {
@Binding var isPlayingAnimation: Bool

let scene = SCNScene(named: "art.scnassets/TestScene.scn")!

func makeUIView(context: Context) -> SCNView {
    // create and add a camera to the scene
    let cameraNode = SCNNode()
    cameraNode.camera = SCNCamera()
    scene.rootNode.addChildNode(cameraNode)

    let scnView = SCNView()
    return scnView
}

func updateUIView(_ scnView: SCNView, context: Context) {
    scnView.scene = scene

    // allows the user to manipulate the camera
    scnView.allowsCameraControl = true

    controlAnimation(isAnimating: isPlayingAnimation, nodeName: "TestNode", animationName: "TestAnimationName")
}

func controlAnimation(isAnimating: Bool, nodeName: String, animationName: String) {
    guard let node = scene.rootNode.childNode(withName: nodeName, recursively: true) else {  return }
    guard let animationPlayer: SCNAnimationPlayer = node.animationPlayer(forKey: animationName) else {  return }
    if isAnimating {
        print("Play Animation")
        animationPlayer.play()
    } else {
        print("Stop Animation")
        animationPlayer.stop()
    }
}
}

struct DogAnimation_Previews: PreviewProvider {
    static var previews: some View {
        ScenekitView(isPlayingAnimation: .constant(true))
    }
}