SpriteKit,Swift 2.0-ScrollView相反 [英] SpriteKit, Swift 2.0 - ScrollView in reverse

查看:82
本文介绍了SpriteKit,Swift 2.0-ScrollView相反的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设法使scrollview可以工作并滚动,但是现在当我滚动时,它只能从右向左滚动,并且想知道如何反转它,以便它从左向右滚动.

这是我的菜单代码,其中包含我的滚动视图:

var moveableNode = SKNode()
var scrollView: CustomScrollView!

private var spriteSize = CGSize.zero

let kMargin: CGFloat = 40

var sprite = SKSpriteNode()

class Menu: SKScene {


override func didMoveToView(view: SKView) {


    addChild(moveableNode)

    spriteSize = SKSpriteNode (imageNamed: "card_level01").size

    let initialMargin = size.width/2
    let marginPerImage = kMargin + spriteSize.width

    scrollView = CustomScrollView(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height), scene: self, moveableNode: moveableNode)

    scrollView.contentSize = CGSizeMake(initialMargin*2 + (marginPerImage * 7), size.height)

    // scrollView.contentSize = CGSizeMake(self.frame.size.width * 2, self.frame.size.height)
    view.addSubview(scrollView)


    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)
        moveableNode.addChild(sprite)

    }

这是我的scrollView类,它是UIScrollView的子类:

 var nodesTouched: [AnyObject] = [] // global

class CustomScrollView: UIScrollView {

// MARK: - Static Properties

/// Touches allowed
static var disabledTouches = false

/// Scroll view
private static var scrollView: UIScrollView!

private static var contentView: UIView!
// MARK: - Properties

/// Current scene
private var currentScene: SKScene?

/// Moveable node
private var moveableNode: SKNode?

// MARK: - Init
init(frame: CGRect, scene: SKScene, moveableNode: SKNode) {
    print("Scroll View init")
    super.init(frame: frame)

    CustomScrollView.scrollView = self
    currentScene = scene
    self.moveableNode = moveableNode
    self.frame = frame
    indicatorStyle = .White
    scrollEnabled = true
    //self.minimumZoomScale = 1
    //self.maximumZoomScale = 3
    canCancelContentTouches = false
    userInteractionEnabled = true
    delegate = self

    //flip for spritekit (only needed for horizontal)
    let verticalFlip = CGAffineTransformMakeScale(-1,-1)
    self.transform = verticalFlip

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


 }

  // MARK: - Touches
 extension CustomScrollView {

/// began
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    print("Touch began scroll view")

    guard !CustomScrollView.disabledTouches else { return }
    currentScene?.touchesBegan(touches, withEvent: event)
    }

/// moved
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    print("Touch moved scroll view")

    guard !CustomScrollView.disabledTouches else { return }
    currentScene?.touchesMoved(touches, withEvent: event)
}

/// ended
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    print("Touch ended scroll view")

    guard !CustomScrollView.disabledTouches else { return }
    currentScene?.touchesEnded(touches, withEvent: event)
}

/// cancelled
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
    print("Touch cancelled scroll view")

    guard !CustomScrollView.disabledTouches else { return }
    currentScene?.touchesCancelled(touches, withEvent: event)
   }
 }

 // MARK: - Touch Controls
extension CustomScrollView {

/// Disable
class func disable() {
    print("Disabled scroll view")
    CustomScrollView.scrollView?.userInteractionEnabled = false
    CustomScrollView.disabledTouches = true
}

/// Enable
class func enable() {
    print("Enabled scroll view")
    CustomScrollView.scrollView?.userInteractionEnabled = true
    CustomScrollView.disabledTouches = false
  }
}

// MARK: - Delegates
extension CustomScrollView: UIScrollViewDelegate {

/// did scroll
func scrollViewDidScroll(scrollView: UIScrollView) {
    print("Scroll view did scroll")

   moveableNode!.position.x = scrollView.contentOffset.x // Left/Right

   //moveableNode!.position.y = scrollView.contentOffset.y // Up/Dowm
   }


}

解决方案

在阅读其余内容之前,您需要先在gitHub(v1.1)上获取我更新的帮助程序.

仅当您的场景缩放模式(gameViewController)设置为

时,我的助手才能真正正常工作

.ResizeFill

因此您的场景不会裁剪.如果您使用其他的scaleMode,例如

.AspectFill 

它可能会在您的scrollView中裁剪您需要调整的内容.

如果您的游戏/应用同时支持纵向和横向模式,那么这也不起作用,无论如何这对游戏来说都是不可能的.

因此,正如我所说,您还注意到在spriteKit中使用ScrollView时,其坐标与UIKit相比有所不同.对于垂直滚动,这实际上没有任何意义,但是对于水平滚动,则一切相反.因此,要解决此问题,请执行以下操作

设置scrollView进行水平滚动,并传递新的scrollDirection属性(在本例中为.Horizo​​ntal)

scrollView = CustomScrollView(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height), scene: self, moveableNode: moveableNode, scrollDirection: .Horizontal)
scrollView.contentSize = CGSizeMake(self.frame.size.width * 3, self.frame.size.height) // * 3 makes it twice as wide as screen
view.addSubview(scrollView)

您还需要在将其添加到视图中之后添加此行代码.

scrollView.setContentOffset(CGPoint(x: 0 + self.frame.size.width * 2, y: 0), animated: true)

这是您用来告诉ScrollView从哪一页开始的行.现在,在此示例中,scrollView的宽度是屏幕的三倍,因此您需要将内容偏移2个屏幕长度

现在,为了使定位更加容易,我将执行此操作,为scrollView的每个页面创建精灵.这样一来,以后定位就容易得多了.

let page1ScrollView = SKSpriteNode(color: SKColor.clearColor(), size: CGSizeMake(self.frame.size.width, self.frame.size.height))
page1ScrollView.position = CGPointMake(CGRectGetMidX(self.frame) - (self.frame.size.width * 2), CGRectGetMidY(self.frame))
moveableNode.addChild(page1ScrollView)

let page2ScrollView = SKSpriteNode(color: SKColor.clearColor(), size: CGSizeMake(self.frame.size.width, self.frame.size.height))
page2ScrollView.position = CGPointMake(CGRectGetMidX(self.frame) - (self.frame.size.width), CGRectGetMidY(self.frame))
moveableNode.addChild(page2ScrollView)

let page3ScrollView = SKSpriteNode(color: SKColor.clearColor(), size: CGSizeMake(self.frame.size.width, self.frame.size.height))
page3ScrollView.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
moveableNode.addChild(page3ScrollView)

现在您可以定位实际的标签,让精灵更加容易.

/// Test label page 1
let myLabel = SKLabelNode(fontNamed:"Chalkduster")
myLabel.text = "Hello, World!"
myLabel.fontSize = 45
myLabel.position = CGPointMake(0, 0)
page1ScrollView.addChild(myLabel)

/// Test sprite page 2
let sprite = SKSpriteNode(color: SKColor.redColor(), size: CGSize(width: 50, height: 50))
sprite.position = CGPointMake(0, 0)
page2ScrollView.addChild(sprite)

/// Test sprite page 3
let sprite2 = SKSpriteNode(color: SKColor.blueColor(), size: CGSize(width: 50, height: 50))
sprite2.position = CGPointMake(0, 0)
page3ScrollView.addChild(sprite2)

希望这会有所帮助.

我还更新了GitHub项目,以更好地对此进行解释

https://github.com/crashoverride777/Swift2-SpriteKit-UIScrollView-Helper

I managed to get a scrollview working and scrolling, but now when I go to scroll it only scrolls from right to left and was wondering how I go about reversing it so it scrolls from left to right instead.

Here is my menu code that contains my scrollview:

var moveableNode = SKNode()
var scrollView: CustomScrollView!

private var spriteSize = CGSize.zero

let kMargin: CGFloat = 40

var sprite = SKSpriteNode()

class Menu: SKScene {


override func didMoveToView(view: SKView) {


    addChild(moveableNode)

    spriteSize = SKSpriteNode (imageNamed: "card_level01").size

    let initialMargin = size.width/2
    let marginPerImage = kMargin + spriteSize.width

    scrollView = CustomScrollView(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height), scene: self, moveableNode: moveableNode)

    scrollView.contentSize = CGSizeMake(initialMargin*2 + (marginPerImage * 7), size.height)

    // scrollView.contentSize = CGSizeMake(self.frame.size.width * 2, self.frame.size.height)
    view.addSubview(scrollView)


    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)
        moveableNode.addChild(sprite)

    }

Here is my scrollView Class that is a subclass of UIScrollView:

 var nodesTouched: [AnyObject] = [] // global

class CustomScrollView: UIScrollView {

// MARK: - Static Properties

/// Touches allowed
static var disabledTouches = false

/// Scroll view
private static var scrollView: UIScrollView!

private static var contentView: UIView!
// MARK: - Properties

/// Current scene
private var currentScene: SKScene?

/// Moveable node
private var moveableNode: SKNode?

// MARK: - Init
init(frame: CGRect, scene: SKScene, moveableNode: SKNode) {
    print("Scroll View init")
    super.init(frame: frame)

    CustomScrollView.scrollView = self
    currentScene = scene
    self.moveableNode = moveableNode
    self.frame = frame
    indicatorStyle = .White
    scrollEnabled = true
    //self.minimumZoomScale = 1
    //self.maximumZoomScale = 3
    canCancelContentTouches = false
    userInteractionEnabled = true
    delegate = self

    //flip for spritekit (only needed for horizontal)
    let verticalFlip = CGAffineTransformMakeScale(-1,-1)
    self.transform = verticalFlip

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


 }

  // MARK: - Touches
 extension CustomScrollView {

/// began
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    print("Touch began scroll view")

    guard !CustomScrollView.disabledTouches else { return }
    currentScene?.touchesBegan(touches, withEvent: event)
    }

/// moved
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    print("Touch moved scroll view")

    guard !CustomScrollView.disabledTouches else { return }
    currentScene?.touchesMoved(touches, withEvent: event)
}

/// ended
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    print("Touch ended scroll view")

    guard !CustomScrollView.disabledTouches else { return }
    currentScene?.touchesEnded(touches, withEvent: event)
}

/// cancelled
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
    print("Touch cancelled scroll view")

    guard !CustomScrollView.disabledTouches else { return }
    currentScene?.touchesCancelled(touches, withEvent: event)
   }
 }

 // MARK: - Touch Controls
extension CustomScrollView {

/// Disable
class func disable() {
    print("Disabled scroll view")
    CustomScrollView.scrollView?.userInteractionEnabled = false
    CustomScrollView.disabledTouches = true
}

/// Enable
class func enable() {
    print("Enabled scroll view")
    CustomScrollView.scrollView?.userInteractionEnabled = true
    CustomScrollView.disabledTouches = false
  }
}

// MARK: - Delegates
extension CustomScrollView: UIScrollViewDelegate {

/// did scroll
func scrollViewDidScroll(scrollView: UIScrollView) {
    print("Scroll view did scroll")

   moveableNode!.position.x = scrollView.contentOffset.x // Left/Right

   //moveableNode!.position.y = scrollView.contentOffset.y // Up/Dowm
   }


}

解决方案

You need get my updated helper on gitHub (v1.1) first before reading the rest.

My helper only really works well when your scene scale mode (gameViewController) is set to

.ResizeFill

so your scenes do not crop. If you use a different scaleMode such as

.AspectFill 

than it might crop stuff in your scrollView which you would need to adjust for.

It also doesnt work if your game/app supports both portrait and landscape, which is unlikely for a game anyway.

So as I said and you have also noticed when using a ScrollView in spriteKit the coordinates are different compared to UIKit. For vertical scrolling this doesn't really mean anything, but for horizontal scrolling everything it is in reverse. So to fix this you do the following

Set up your scrollView for horizontal scrolling, passing along the new scrollDirection property (.Horizontal in this case)

scrollView = CustomScrollView(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height), scene: self, moveableNode: moveableNode, scrollDirection: .Horizontal)
scrollView.contentSize = CGSizeMake(self.frame.size.width * 3, self.frame.size.height) // * 3 makes it twice as wide as screen
view.addSubview(scrollView)

you need to also add this line of code after adding it to the view.

scrollView.setContentOffset(CGPoint(x: 0 + self.frame.size.width * 2, y: 0), animated: true)

this is the line you use to tell the ScrollView on which page to start. Now in this example the scrollView is three times as wide as the screen, therefore you need to offset the content by 2 screen lengths

Now to make things easier for positioning I would do this, create sprites for each page of the scrollView. This makes positioning much easier later on.

let page1ScrollView = SKSpriteNode(color: SKColor.clearColor(), size: CGSizeMake(self.frame.size.width, self.frame.size.height))
page1ScrollView.position = CGPointMake(CGRectGetMidX(self.frame) - (self.frame.size.width * 2), CGRectGetMidY(self.frame))
moveableNode.addChild(page1ScrollView)

let page2ScrollView = SKSpriteNode(color: SKColor.clearColor(), size: CGSizeMake(self.frame.size.width, self.frame.size.height))
page2ScrollView.position = CGPointMake(CGRectGetMidX(self.frame) - (self.frame.size.width), CGRectGetMidY(self.frame))
moveableNode.addChild(page2ScrollView)

let page3ScrollView = SKSpriteNode(color: SKColor.clearColor(), size: CGSizeMake(self.frame.size.width, self.frame.size.height))
page3ScrollView.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
moveableNode.addChild(page3ScrollView)

and now you can positioning your actual labels, sprites much easier.

/// Test label page 1
let myLabel = SKLabelNode(fontNamed:"Chalkduster")
myLabel.text = "Hello, World!"
myLabel.fontSize = 45
myLabel.position = CGPointMake(0, 0)
page1ScrollView.addChild(myLabel)

/// Test sprite page 2
let sprite = SKSpriteNode(color: SKColor.redColor(), size: CGSize(width: 50, height: 50))
sprite.position = CGPointMake(0, 0)
page2ScrollView.addChild(sprite)

/// Test sprite page 3
let sprite2 = SKSpriteNode(color: SKColor.blueColor(), size: CGSize(width: 50, height: 50))
sprite2.position = CGPointMake(0, 0)
page3ScrollView.addChild(sprite2)

Hope this helps.

I also updated my GitHub project to explain this better

https://github.com/crashoverride777/Swift2-SpriteKit-UIScrollView-Helper

这篇关于SpriteKit,Swift 2.0-ScrollView相反的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆