简体   繁体   English

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

[英]iCarousel on Game Swift+SpriteKit not working properly

I'm trying to add an iCarousel to my game that will be displayed in the MainMenu, where you will be able to select an item and unlock others while you play and do more progress within the game. 我正在尝试将iCarousel添加到我的游戏中,该游戏将显示在MainMenu中,您可以在其中选择一个项目并在玩游戏时解锁其他项目并在游戏中取得更大的进步。

Tried looking into a few tutorials but i still have some problems and i can't figure it out. 尝试查看一些教程,但是我仍然有一些问题,我无法弄清楚。

This is the post I based my current code on and also this github 这是我基于当前代码的帖子 ,也是这个github

But the structure on that "SpriteKit iCarousel" github is different than mine too. 但是“ SpriteKit iCarousel” github上的结构也与我的不同。

I can make the carousel be displayed but doesn't even work, and is also located on top-left of the screen like "stucked" for some reason. 我可以显示该轮播,但什至无法运行,并且由于某种原因它也位于屏幕的左上角,像“被卡住”。

So this is my GameViewController.swift code: 这是我的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
    }
}

And this is what i'm doing on MenuScene.swift 这就是我在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)

}

And then, on touchesEnded i'm calling from a button touch self.showBallPicker() to display the carousel. 然后,在touchesEnded上,我从按钮触摸self.showBallPicker()进行调用以显示轮播。

As I said before, it's adding the carousel, but not even working and on top-left corner. 就像我之前说的,它添加了轮播,但在左上角甚至没有工作。

How can I achieve this? 我该如何实现? Once I can make it display properly, I can handle the rest. 一旦可以正确显示它,我就可以处理其余的事情。

Thanks. 谢谢。

You're not setting the frame of the carousel or setting constraints on it. 您没有设置轮播框架或对其设置约束。

Try changing your setupCarousel method to: 尝试将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)
}

Update 更新资料

These constraints will pin the carousel to the edges of your view controller's view. 这些约束会将轮播固定在视图控制器视图的边缘。 If you want to position it differently, you could, for example, replace those constraints with something like: 如果要以不同的方式放置它,例如,可以将约束替换为以下内容:

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

This will center the carousel horizontally and place the carousel 100 points up from the center vertically. 这将使转盘水平居中,并将转盘从中心垂直向上放置100个点。 The carousel will be the same width as it's superview but will always be 200 points tall. 旋转木马的宽度与被监视物体的宽度相同,但始终为200点高。 You can look at Apple's documentation for more options for using anchors to create constraints. 您可以查看Apple的文档,以获得更多使用锚点创建约束的选项。

If you want to add labels to your carousel items you should do that in viewForItemAtIndex . 如果要向轮播项目添加标签,则应在viewForItemAtIndex You can create a simple UIView subclass that will hold a UIImageView and UILabel and return that instead of just a UIImageView . 您可以创建一个简单的UIView子类,该子类将保存UIImageViewUILabel并将其返回,而不仅仅是UIImageView For example: 例如:

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
    }
}

Now in viewForItemAtIndex 现在在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
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM