ios - 使用 Swift 时 iOS 7.1 和 8 之间的不同结果

标签 ios swift ios8 ios7.1 xcode6

我正在通过编写一个简单的游戏来练习 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/

相关文章:

ios - 使用 NSScanner 过滤字符串并删除数字字符后的空格

ios - 使用 CallKit 切换扬声器和从扬声器切换

ios8 - 红色录音状态栏 "flashes"而应用程序在*前台*

ios - 每个 AVPlayerLayer 一个 AVPlayer 与多个 AVPlayer

iphone - 使用 NSLog 或 CCLog 生成的日志是否存储在 iPhone 中?我可以找回它们吗?

ios - 如何播放/停止背景音乐和音效?

objective-c - containerURLForSecurityApplicationGroupIdentifier 在 iOS 模拟器上返回 nil

uitableview - swift - 错误 : unexpectedly found nil while unwrapping an optional value

ios - XMPPFramework - 不断收到错误代码 503 服务不可用

医疗保健应用程序的 iOS 后台执行