【问题标题】:Swift: Using switch statement in touchesBeganSwift:在 touchesBegan 中使用 switch 语句
【发布时间】:2017-03-03 17:33:50
【问题描述】:

我想在SKScene 中清理我的touchesBegan(..)。我想做一个案例陈述而不是我的if .. else 链。但是,我在实施时遇到错误,这表明我不知道平等是如何在幕后完成的。

代码前:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    for touch: AnyObject in touches {
        let location = touch.locationInNode(self)

        if self.nodeAtPoint(location) === playLabel {
            buildLevelSelect()
        } else if self.nodeAtPoint(location) === aboutLabel {
            createAboutView()
        } else if self.nodeAtPoint(location) === storeLabel {
            createStore()
        }
    }
}

代码后:点击后,一些标签点击工作,但其他一些引发Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode 0x0)错误:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    for touch: AnyObject in touches {
        let location = touch.locationInNode(self)

        switch(self.nodeAtPoint(location)){
        case playLabel :
            buildLevelSelect()
        case aboutLabel :
            createAboutView()
        case storeLabel :
            createStore()
        default : break
    }
}

【问题讨论】:

    标签: ios swift sprite-kit switch-statement skscene


    【解决方案1】:

    如果你想要=== 的行为,你可以编写一种看起来很奇怪但功能齐全的switch,如下所示:

    switch(true){
            case self.nodeAtPoint(location) === playLabel : buildLevelSelect()
            case self.nodeAtPoint(location) === aboutLabel : createAboutView()
            case self.nodeAtPoint(location) === storeLabel : createStore()
            default : break
    }
    

    在我看来,这仍然比 if-else 链看起来更干净。

    【讨论】:

    • 哦...跳出框框思考。我喜欢这个。在接受答案之前,我会等一两天去感受别人的感受。
    【解决方案2】:

    完成此操作的最简单方法是填充节点的.name 属性,这样您就可以改用名称。那么你的开关应该是这样的:

    switch (self.nodeAtPoint(location).name ?? "") { 
        case "playLabel" :
            buildLevelSelect()
        case "aboutLabel" :
            ...
    

    【讨论】:

    • 这是最好的方法。 @cdpalmer 您应该检查一个字符串是否等于另一个字符串(名称),而不是比较两个可能不同的对象如果您使用二元运算符 === (例如,如果一个是 String 而另一个是 NSString,则两个相同的字符串会返回崩溃)...
    • 这是有道理的。我将不得不进行一些重构,我只是想通你可以在我的副项目中途将字符串名称绑定到对象。
    【解决方案3】:

    您还可以在 switch 语句中转换对象,然后您的代码按预期工作

        if let touch = touches.first as UITouch! {
    
            let touchLocation = touch.location(in: self)
    
            switch self.atPoint(touchLocation) {
                case redBox as SKSpriteNode:
                    print("touched redBox")
                case greenBox as SKSpriteNode:
                    print("touched greenBox")
                default:
                    print("touched nothing")
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-06
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      相关资源
      最近更新 更多