[英]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)
}
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
子类,该子类将保存UIImageView
和UILabel
并将其返回,而不仅仅是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.