【问题标题】:iCarousel on Game Swift+SpriteKit not working properlyGame Swift+SpriteKit 上的 iCarousel 无法正常工作
【发布时间】:2016-08-02 01:38:49
【问题描述】:

我正在尝试将iCarousel 添加到我的游戏中,该iCarousel 将显示在 MainMenu 中,您可以在游戏中选择一个项目并解锁其他项目并在游戏中取得更多进展。

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

这是post 我基于我当前的代码,也是这个github

但是“SpriteKit iCarousel”github 上的结构也与我的不同。

我可以让轮播显示出来但甚至不起作用,并且由于某种原因也像“卡住”一样位于屏幕的左上角。

这是我的 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 时,我从一个按钮 touch self.showBallPicker() 调用以显示轮播。

正如我之前所说,它正在添加轮播,但甚至无法正常工作并且位于左上角。

我怎样才能做到这一点?一旦我可以让它正确显示,我就可以处理其余的了。

谢谢。

【问题讨论】:

    标签: ios swift sprite-kit icarousel


    【解决方案1】:

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

    尝试将您的 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 点。轮播将与它的超级视图具有相同的宽度,但始终为 200 点高。您可以查看 Apple 的文档,了解更多使用锚点创建约束的选项。

    如果您想为您的轮播项目添加标签,您应该在viewForItemAtIndex 中执行此操作。您可以创建一个简单的UIView 子类,该子类将包含UIImageView 和UILabel 并返回它而不仅仅是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
        }
    

    【讨论】:

    • 天哪!等我回家试试!!感谢回复:)
    • omgggg,你真是个天才!!!!你解决了!现在放置正确!,你知道我怎样才能给 iCarousel 添加效果吗?是否可以?也许“缩放”到您要选择的那个?非常感谢Beyowulf。我知道你可以解决它:)
    • 嗯,这很奇怪。当我在轮播中选择一个项目时,它会显示我隐藏的广告横幅,并且按钮不再起作用,你知道会这样吗?
    • 缩放本质上不是.Rotary类型吗?我在您的代码中没有看到广告横幅,所以我不确定。似乎您在didSelectItemAtIndex 中实例化了一个新的MenuScene:let scene = MenuScene(size:self.view.bounds.size)。好像你应该说if let skView = self.view as? SKView, let menuScene = skView.scene as? MenuScene { menuScene. imageName = self.imageArray[index] as! String }。这只是获取对已经实例化和呈现的场景的引用,然后设置其imageName 属性。
    • 你应该看看我谈论子类化iCarousel的另一部分,所以轮播项目之外的触摸事件被传递给SKView。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多