问题描述
我设法让一个滚动视图工作并滚动,但现在当我滚动它时,它只会从右向左滚动,我想知道如何将它反转,以便它从左向右滚动.
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)
}
这是我的 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) 上获取我的更新助手.
You need get my updated helper on gitHub (v1.1) first before reading the rest.
只有当您的场景缩放模式(gameViewController)设置为时,我的助手才能真正发挥作用
My helper only really works well when your scene scale mode (gameViewController) is set to
.ResizeFill
因此您的场景不会被裁剪.如果您使用不同的 scaleMode,例如
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.
正如我所说,您也注意到在 spriteKit 中使用 ScrollView 时,坐标与 UIKit 不同.对于垂直滚动,这实际上没有任何意义,但对于水平滚动,一切都是相反的.因此,要解决此问题,请执行以下操作
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
设置你的scrollView进行水平滚动,传递新的scrollDirection属性(在本例中为.Horizontal)
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)
这是您用来告诉 ScrollView 从哪个页面开始的行.现在在这个例子中,scrollView 的宽度是屏幕的三倍,因此您需要将内容偏移 2 个屏幕长度
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)
希望这会有所帮助.
我还更新了我的 GitHub 项目以更好地解释这一点
I also updated my GitHub project to explain this better
https://github.com/crashoverride777/Swift2-SpriteKit-UIScrollView-Helper
这篇关于SpriteKit,Swift 2.0 - 反向滚动视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!