Swift:简化菜单button逻辑

我在Swift中有一个游戏,每个关卡都是一个从GameScene基类inheritance而来的单独的类(这样做对于我所做的事来说更简单了,不要评价我)。 我也有一个菜单,每个级别都有一个button。 这是button如何加载级别:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { if let t = touches.first { let node = atPoint(t.location(in: self)) if let name = node.name { let newScene: GameScene! switch Int(name)! { case 1: newScene = Level1(size: frame.size) case 2: newScene = Level2(size: frame.size) case 3: newScene = Level3(size: frame.size) case 4: newScene = Level4(size: frame.size) case 5: newScene = Level5(size: frame.size) case 6: newScene = Level6(size: frame.size) case 7: newScene = Level7(size: frame.size) default: newScene = Level1(size: frame.size) } view?.presentScene(newScene, transition: .crossFade(withDuration: 0.5)) } } } 

对我来说,这个开关看起来难以置信的丑陋和毫无意义,但我想不出一个办法来避免它。 我希望有人能帮助我,我只是想不出一个更好的select。

您可以先将Level的类名构造为string"Level\(name)" ,然后通过将名称传递给函数来获取实际需要的类:

 func classFromString(_ className: String) -> AnyClass! { let namespace = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String let cls: AnyClass = NSClassFromString("\(namespace).\(className)")! return cls } 

用法示例:

 let className = "Level1" let levelInstance = (classFromString(className) as! GameScene).init(size: frame.size) 

…但当然,最好的build议是避免这种架构

你可以这样做:

  var newScene: GameScene! //Level1 is repeating on 0 and 1'st index let arrScene : [GameScene] = [Level1(size: frame.size),Level1(size: frame.size),Level2(size: frame.size),Level3(size: frame.size),Level4(size: frame.size),Level5(size: frame.size),Level6(size: frame.size),Level7(size: frame.size)] if Int(name)! <=7 && Int(name)! > 0{ newScene = arrScene[Int(name)!] }else{ //Default level1 newScene = arrScene[0] }