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,他们不应该相互了解。