游戏上的 iCarousel Swift+SpriteKit 无法正常工作

iCarousel on Game Swift+SpriteKit not working properly

我正在尝试向我的游戏中添加一个 iCarousel,它将显示在主菜单中,您可以在其中 select 一个项目并在玩游戏和做更多事情的同时解锁其他项目游戏中的进度。

尝试查看了一些教程,但我仍然遇到一些问题,我无法弄清楚。

这是 I based my current code on and also this github

但是 "SpriteKit iCarousel" github 上的结构也和我的不一样。

我可以显示旋转木马,但它甚至不起作用,并且出于某种原因也像 "stucked" 一样位于屏幕的左上角。

所以这是我的 GameViewController.swift 代码:

import UIKit
import SpriteKit
import GameKit

class GameViewController: UIViewController, iCarouselDataSource, iCarouselDelegate {


    var imageArray: NSMutableArray = NSMutableArray()
    var selectedIndex: Int!
    var carousel : iCarousel!

    deinit{
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

    func showCarousel(){
        carousel.hidden = false
    }
    func hideCarousel(){
        carousel.hidden = true
    }

    override func awakeFromNib(){
        super.awakeFromNib()
        self.imageArray = NSMutableArray(array: ["white","white2","white3"])
    }

    func carousel(carousel:iCarousel, didSelectItemAtIndex index:NSInteger)   {

        let scene = MenuScene(size:self.view.bounds.size)
        scene.imageName = self.imageArray[index] as! String
        self.hideCarousel()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        self.authenticateLocalPlayer()
        self.setupCarousel()
    }

    func setupCarousel() {
        carousel = iCarousel()
        carousel.dataSource = self
        carousel.delegate = self
        carousel.type = .Linear
        carousel.reloadData()

        let spriteKitView = SKView()
        spriteKitView.frame = CGRectMake(0, 0, 250, 250)
//        self.view.insertSubview(spriteKitView, belowSubview: self.carousel) // this is showing an empty gray box 
        self.view.addSubview(self.carousel)

        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.showCarousel), name: "showBallPicker", object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.hideCarousel), name: "hideBallPicker", object: nil)
    }

    func carousel(carousel: iCarousel, valueForOption option: iCarouselOption, withDefault value: CGFloat) -> CGFloat{

        if (option == .Spacing){
            return value * 2
        }

        return value
    }

    func carousel(carousel: iCarousel, viewForItemAtIndex index: Int, reusingView view: UIView?) -> UIView {
        var imageView: UIImageView!

        if view == nil {
            imageView = UIImageView(frame: CGRectMake(0, 0, 250, 250))
            imageView.backgroundColor = UIColor.redColor()
            imageView.contentMode = .ScaleAspectFill
        }else{
            imageView = view as! UIImageView
        }

        imageView.image = UIImage(named: "\(imageArray.objectAtIndex(index))")

        return imageView
    }

    func numberOfItemsInCarousel(carousel: iCarousel) -> Int {
        return imageArray.count
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        let skView = self.view as! SKView

        if skView.scene == nil {
            skView.showsFPS = true
            skView.showsNodeCount = true
            skView.showsPhysics = false
            skView.multipleTouchEnabled = true

            let menuScene = MenuScene(size: CGSizeMake(375,667))
            menuScene.scaleMode = .AspectFill
            menuScene.imageName = self.imageArray[0] as! String

            self.hideCarousel()
            skView.presentScene(menuScene)
        }
    }

    override func viewWillDisappear(animated: Bool) {
        if let skView = self.view as? SKView {
            skView.presentScene(nil)
        }
    }

    override func viewDidDisappear(animated: Bool) {
        if let skView = self.view as? SKView {
            skView.presentScene(nil)
        }
    }

    override func prefersStatusBarHidden() -> Bool {
        return true
    }
}

这就是我在 MenuScene.swift

上所做的
var childNode = SKSpriteNode()
var imageName = "white"{
    didSet{
        self.childNode.texture = SKTexture(imageNamed: imageName)
    }
}

func showBallPicker(){
    NSNotificationCenter.defaultCenter().postNotificationName("showBallPicker", object: nil)
}

override init(size: CGSize) {
     // here im supposed to create a childNode SKSpriteNode, but for what? it only adds the same image of the carousel and that's it.
    self.childNode = SKSpriteNode(imageNamed: imageName)
    self.childNode.anchorPoint = CGPointZero
    self.childNode.zPosition = 30
    self.childNode.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
    self.addChild(self.childNode)

}

然后,在 touchesEnded 上,我通过触摸按钮调用 self.showBallPicker() 以显示轮播。

正如我之前所说,它正在添加轮播,但甚至没有工作并且在左上角。

我怎样才能做到这一点?一旦我可以让它正常显示,我就可以处理剩下的事情。

谢谢。

您没有设置轮播框架或对其设置约束。

尝试将您的 setupCarousel 方法更改为:

func setupCarousel() {
        carousel = iCarousel()
        carousel.dataSource = self
        carousel.delegate = self
        carousel.type = .Linear
        carousel.reloadData()
        // turn off autoresizing mask
        carousel.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(self.carousel)
        // Add constraints
        carousel.topAnchor.constraintEqualToAnchor(self.topLayoutGuide.bottomAnchor).active = true
        carousel.leadingAnchor.constraintEqualToAnchor(self.view.leadingAnchor).active = true
        carousel.trailingAnchor.constraintEqualToAnchor(self.view.trailingAnchor).active = true
        carousel.bottomAnchor.constraintEqualToAnchor(self.view.bottomAnchor).active = true

        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.showCarousel), name: "showBallPicker", object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.hideCarousel), name: "hideBallPicker", object: nil)
}

更新

这些约束会将轮播固定到视图控制器视图的边缘。如果您想以不同的方式定位它,例如,您可以将这些约束替换为:

carousel.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor).active = true
carousel.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor, constant: -100).active = true
carousel.widthAnchor.constraintEqualToAnchor(self.view.widthAnchor).active = true
carousel.heightAnchor.constraintEqualToConstant(200.0).active = true

这将使转盘水平居中,并将转盘垂直放置在距中心 100 点的位置。 carousel 的宽度与它的 superview 相同,但始终为 200 点高。您可以查看 Apple 的文档,了解更多使用锚点创建约束的选项。

如果您想为轮播项目添加标签,您应该在 viewForItemAtIndex 中进行。您可以创建一个简单的 UIView 子类,它将包含 UIImageViewUILabel 以及 return 而不仅仅是 UIImageView。例如:

class CarouselItem: UIView {
    let imageView:UIImageView =
    {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.contentMode = .ScaleAspectFill
        return imageView
    }()

    let label:UILabel =
    {
        let label = UILabel()
        label.adjustsFontSizeToFitWidth = true
        label.minimumScaleFactor = 0.5
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textAlignment = .Center
        label.numberOfLines = 0
        return label
    }()

    override init(frame: CGRect)
    {
        super.init(frame: frame)
        self.commonInit()
    }

    required init?(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)
        self.commonInit()
    }

    func commonInit()
    {
        self.addSubview(self.imageView)
        self.addSubview(self.label)

        self.imageView.topAnchor.constraintEqualToAnchor(self.topAnchor).active = true
        self.imageView.centerXAnchor.constraintEqualToAnchor(self.centerXAnchor).active = true
        self.imageView.widthAnchor.constraintEqualToAnchor(self.widthAnchor).active = true
        self.imageView.heightAnchor.constraintEqualToAnchor(self.heightAnchor, multiplier: 0.9).active = true

        self.label.topAnchor.constraintEqualToAnchor(self.imageView.bottomAnchor, constant: 8.0).active = true
        self.label.centerXAnchor.constraintEqualToAnchor(self.centerXAnchor).active = true
    }
}

现在 viewForItemAtIndex

func carousel(carousel: iCarousel, viewForItemAtIndex index: Int, reusingView view: UIView?) -> UIView {
        var carouselItem: CarouselItem!

        if view == nil {
            carouselItem = CarouselItem(frame: CGRectMake(0, 0, 250, 250))
            carouselItem.backgroundColor = UIColor.redColor()
        }else{
            carouselItem = view as! CarouselItem
        }

        carouselItem.imageView.image = UIImage(named: "\(imageArray.objectAtIndex(index))")
        carouselItem.label.text = "Some Text"

        return carouselItem
    }