SpriteKit,Swift 2.0 - 通过按钮启动场景时缺少 ScrollView
SpriteKit, Swift 2.0 - ScrollView Missing from Scene Startup via Button
我最近在我的 GameViewController 中实现了一个 scrollView,它工作得非常好,但我看到的教程只有一个场景,即启动场景 (GameScene),而不是我将要成为的单独场景调用 "Menu" 所以我设法让它启动菜单场景而不是常规的 "GameScene" 但是当我使用我在 GameScene 中实现的按钮从 GameScene 转到菜单场景时,滚动视图不起作用,但它确实显示了图片,但我无法滚动浏览它们。
我的问题是,当我使用按钮(在 GameScene 中)转到菜单场景时,如何让 scrollView 工作?
这是按钮(在 GameScene 中)
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch: UITouch = touches.first!
let location: CGPoint = touch.locationInNode(self)
let node: SKNode = self.nodeAtPoint(location)
if (node == menubutton) {
let MenuScene = Menu(size: self.size, viewController: viewController)
let transition = SKTransition.flipVerticalWithDuration(0.5)
MenuScene.scaleMode = SKSceneScaleMode.AspectFill
self.scene!.view?.presentScene(MenuScene, transition: transition)
}
这是我的菜单场景:
import Foundation
import SpriteKit
let kMargin: CGFloat = 40
var backButton = SKSpriteNode()
var selectButton = SKSpriteNode()
class Menu: SKScene {
let world2 = SKSpriteNode()
private var imageSize = CGSize.zero
private weak var viewController: GameViewController?
init(size: CGSize, viewController: GameViewController?) {
self.viewController = viewController
super.init(size: size)
}
required init?(coder aDecoder: NSCoder) {
assert(false, "Use init(size:viewController:)")
super.init(coder: aDecoder)
}
override func didMoveToView(view: SKView) {
physicsWorld.gravity = CGVector.zero
imageSize = SKSpriteNode(imageNamed: "card_level01").size
let initialMargin = size.width/2
let marginPerImage = kMargin + imageSize.width
world2.size = CGSize(width: initialMargin*2 + (marginPerImage * 7), height: size.height)
addChild(world2)
for i in 1...8 {
let sprite = SKSpriteNode(imageNamed: String(format: "card_level%02d", i))
sprite.position = CGPoint(x: initialMargin + (marginPerImage * (CGFloat(i) - 1)), y: size.height / 2)
world2.addChild(sprite)
}
}
override func update(currentTime: NSTimeInterval) {
viewController?.applyScrollViewToSpriteKitMapping()
}
这是我的 GameViewController
import UIKit
import SpriteKit
class GameViewController: UIViewController {
var scrollView: UIScrollView!
var contentView: UIView!
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let skView = view as! SKView
if (skView.scene === Menu.self) {
skView.showsFPS = true
skView.showsNodeCount = true
skView.ignoresSiblingOrder = true
let scene = Menu(size: skView.bounds.size, viewController: self)
scene.scaleMode = .AspectFill
skView.presentScene(scene)
scrollView = UIScrollView(frame: self.view.bounds)
scrollView.delegate = self
scrollView.contentSize = scene.world2.frame.size
view.addSubview(scrollView)
contentView = UIView(frame: CGRect(origin: CGPoint.zero, size: scene.world2.size))
contentView.backgroundColor = UIColor.greenColor().colorWithAlphaComponent(0.2)
scrollView.addSubview(contentView)
applyScrollViewToSpriteKitMapping()
}
}
func applyScrollViewToSpriteKitMapping() {
let origin = contentView.frame.origin
let skPosition = CGPoint(x: -scrollView.contentOffset.x + origin.x, y: -scrollView.contentSize.height + CGRectGetHeight(view.bounds) + scrollView.contentOffset.y - origin.y)
let skView = view as! SKView
if let scene = skView.scene as? Menu {
scene.world2.position = skPosition
}
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
return UIInterfaceOrientationMask.Portrait
} else {
return UIInterfaceOrientationMask.All
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override func shouldAutorotate() -> Bool {
return true
}
override func prefersStatusBarHidden() -> Bool {
return true
}
}
extension GameViewController: UIScrollViewDelegate {
}
我最近帮另一个会员解决了类似的问题,看看可能对你有帮助
以我的方式,我将滚动视图子类化,因此可以将它直接添加到 SKScenes 而不是视图控制器。
如果您希望 1 个以上的 SKScene 上的 scrollView 没有重复代码,则需要子类化您的 SKScnenes
class BaseScene: SKScene ...
// Add scroll view
class Menu: BaseScene...
class GameScene: BaseScene ...
附带说明一下,您不应该真正在您的 SKScenes 中引用您的 viewController,他们不应该相互了解。
我最近在我的 GameViewController 中实现了一个 scrollView,它工作得非常好,但我看到的教程只有一个场景,即启动场景 (GameScene),而不是我将要成为的单独场景调用 "Menu" 所以我设法让它启动菜单场景而不是常规的 "GameScene" 但是当我使用我在 GameScene 中实现的按钮从 GameScene 转到菜单场景时,滚动视图不起作用,但它确实显示了图片,但我无法滚动浏览它们。
我的问题是,当我使用按钮(在 GameScene 中)转到菜单场景时,如何让 scrollView 工作?
这是按钮(在 GameScene 中)
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch: UITouch = touches.first!
let location: CGPoint = touch.locationInNode(self)
let node: SKNode = self.nodeAtPoint(location)
if (node == menubutton) {
let MenuScene = Menu(size: self.size, viewController: viewController)
let transition = SKTransition.flipVerticalWithDuration(0.5)
MenuScene.scaleMode = SKSceneScaleMode.AspectFill
self.scene!.view?.presentScene(MenuScene, transition: transition)
}
这是我的菜单场景:
import Foundation
import SpriteKit
let kMargin: CGFloat = 40
var backButton = SKSpriteNode()
var selectButton = SKSpriteNode()
class Menu: SKScene {
let world2 = SKSpriteNode()
private var imageSize = CGSize.zero
private weak var viewController: GameViewController?
init(size: CGSize, viewController: GameViewController?) {
self.viewController = viewController
super.init(size: size)
}
required init?(coder aDecoder: NSCoder) {
assert(false, "Use init(size:viewController:)")
super.init(coder: aDecoder)
}
override func didMoveToView(view: SKView) {
physicsWorld.gravity = CGVector.zero
imageSize = SKSpriteNode(imageNamed: "card_level01").size
let initialMargin = size.width/2
let marginPerImage = kMargin + imageSize.width
world2.size = CGSize(width: initialMargin*2 + (marginPerImage * 7), height: size.height)
addChild(world2)
for i in 1...8 {
let sprite = SKSpriteNode(imageNamed: String(format: "card_level%02d", i))
sprite.position = CGPoint(x: initialMargin + (marginPerImage * (CGFloat(i) - 1)), y: size.height / 2)
world2.addChild(sprite)
}
}
override func update(currentTime: NSTimeInterval) {
viewController?.applyScrollViewToSpriteKitMapping()
}
这是我的 GameViewController
import UIKit
import SpriteKit
class GameViewController: UIViewController {
var scrollView: UIScrollView!
var contentView: UIView!
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let skView = view as! SKView
if (skView.scene === Menu.self) {
skView.showsFPS = true
skView.showsNodeCount = true
skView.ignoresSiblingOrder = true
let scene = Menu(size: skView.bounds.size, viewController: self)
scene.scaleMode = .AspectFill
skView.presentScene(scene)
scrollView = UIScrollView(frame: self.view.bounds)
scrollView.delegate = self
scrollView.contentSize = scene.world2.frame.size
view.addSubview(scrollView)
contentView = UIView(frame: CGRect(origin: CGPoint.zero, size: scene.world2.size))
contentView.backgroundColor = UIColor.greenColor().colorWithAlphaComponent(0.2)
scrollView.addSubview(contentView)
applyScrollViewToSpriteKitMapping()
}
}
func applyScrollViewToSpriteKitMapping() {
let origin = contentView.frame.origin
let skPosition = CGPoint(x: -scrollView.contentOffset.x + origin.x, y: -scrollView.contentSize.height + CGRectGetHeight(view.bounds) + scrollView.contentOffset.y - origin.y)
let skView = view as! SKView
if let scene = skView.scene as? Menu {
scene.world2.position = skPosition
}
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
return UIInterfaceOrientationMask.Portrait
} else {
return UIInterfaceOrientationMask.All
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override func shouldAutorotate() -> Bool {
return true
}
override func prefersStatusBarHidden() -> Bool {
return true
}
}
extension GameViewController: UIScrollViewDelegate {
}
我最近帮另一个会员解决了类似的问题,看看可能对你有帮助
以我的方式,我将滚动视图子类化,因此可以将它直接添加到 SKScenes 而不是视图控制器。
如果您希望 1 个以上的 SKScene 上的 scrollView 没有重复代码,则需要子类化您的 SKScnenes
class BaseScene: SKScene ...
// Add scroll view
class Menu: BaseScene...
class GameScene: BaseScene ...
附带说明一下,您不应该真正在您的 SKScenes 中引用您的 viewController,他们不应该相互了解。