我正在通过编写一个简单的游戏来练习 swift。然而,我注意到发生了一些奇怪的事情。与 iOS 8 相比,当我在 iOS 7.1 上运行我的应用程序时,得到了不同的结果。我试图将 SKNode 向下转换为我编写的名为 CircleNode 的自定义类,该类继承自 SKSpriteNode。这是类(class):
import UIKit
import SpriteKit
class CircleNode: SKSpriteNode {
var _hasMoved = false
var _touchingCircles:NSMutableArray = NSMutableArray()
var _isTouchingObject = false
var _selectedForDeletion = false
var _isBeingTouched = false
var _xOffset:CGFloat = 0
var _yOffset:CGFloat = 0
func addTouchingCircle(touchingCircle:CircleNode) {
_touchingCircles.addObject(touchingCircle)
_isTouchingObject = true
}
func removeAllCircles(){
self._selectedForDeletion = true
for circ :CircleNode! in _touchingCircles {
if circ._selectedForDeletion == false {
circ.removeAllCircles()
}
}
self.removeFromParent()
}
}
导致奇怪结果的代码是:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
for touch: AnyObject in touches {
let locationInScene = touch.locationInNode(self)
var selectedNode = self.nodeAtPoint(locationInScene)
let node = selectedNode as? CircleNode
if node {
println("NODE FOUND:circle")
} else {
println("NULL")
}
}
}
在 iOS 8 中,当我单击屏幕上的一个圆圈时,它会打印“NODE FOUND:circle”。但是,当我在 iOS 7.1 上执行相同操作时,它会打印“NULL”。几天来我一直试图弄清楚为什么会发生这种情况,但我似乎无法弄清楚。看起来在 iOS 8 中, var selectedNode = self.nodeAtPoint(locationInScene)
实际上返回了我的 CircleNode,但在 iOS 7.1 中,它无法识别该节点。有什么帮助吗?提前致谢!
最佳答案
XCode 模板在 XCode 6.0 和 6.1 之间的更改方式似乎存在问题,导致在 Swift 中使用 SpriteKit 场景时出现问题。
问题实际上在于 Controller 中 SKScene 的初始化,而不是节点本身:XCode 6.1 实现了“unarchiveFromFile”扩展方法,该方法似乎不适用于 iOS7.1 上的 Swift
我通过使用以下扩展解决了这个问题:
import UIKit
import SpriteKit
extension SKNode {
class func unarchiveFromFile<T: SKScene>(file : NSString) -> T {
let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks")
var sceneData = NSData(contentsOfFile: path!, options: .DataReadingMappedIfSafe, error: nil)
var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData!)
archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as T
archiver.finishDecoding()
return scene
}
class func safeInit<T: SKScene>(size: CGSize, _ skFile: NSString) -> T {
let currentVersion = UIDevice.currentDevice().systemVersion
let isIOS8 = currentVersion.compare("8.0", options: NSStringCompareOptions.NumericSearch) != NSComparisonResult.OrderedAscending
if isIOS8 {
let scene = T.unarchiveFromFile(skFile)
scene.size = size
return scene as T
} else {
return T(size: size)
}
}
}
然后使用以下代码从 Controller 调用它:
let skView = self.view as SKView
let scene = GameScene.safeInit(skView.bounds.size, "GameScene") as GameScene
这似乎对我有用。感觉有点像黑客,但我看不到任何真正有效的替代选项。
关于ios - 使用 Swift 时 iOS 7.1 和 8 之间的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24738224/