3

基本上我需要在我的 SpriteKit 项目中创建一个 UIScrollView,但是我在添加 SKButtons(用于按钮管理的自定义 SKNode 类)时遇到了很多问题。所以我开始创建一个带有触摸手势的可滚动 SKNode,但显然,这个栏不会有原生的 UIScrollView 加速:我正在寻找的功能。

所以试图通过添加一个原生 UIScrollView 来解决这个问题,并捕捉每一个位置变化,像这样:

在此处输入图像描述

使用此代码:

-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    [blueNode setPosition:CGPointMake(blueNode.position.x, scrollerUI.contentOffset)];
}

这很好用,但愚蠢地我忘记了,如果我添加按钮,触摸手势将无法识别按钮的触摸事件!(UIScrollView 具有优先权)。

也许只是一个愚蠢的问题,但我真的不知道如何弄清楚。也许编写我自己的加速方法?

4

2 回答 2

2

一种可能的解决方案是向场景添加点击手势:

override func didMoveToView(view: SKView) {
    let tap : UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("tapped:"))
    view.addGestureRecognizer(tap)
}

func tapped(tap : UITapGestureRecognizer) {
    let viewLocation = tap.locationInView(tap.view)
    let location = convertPointFromView(viewLocation)
    let node = nodeAtPoint(location)

    if node.name == "lvlButton" {
        var button = node as! SKButton
        button.touchBegan(location)
    }
}
于 2015-02-26T19:05:37.180 回答
2

我想我想出了一个处理触摸的解决方案。由于UIScrollView吃掉了所有的触摸以使其滚动,因此您需要将它们传递给SKScene. 您可以通过子类化来做到这一点UIScrollView

class SpriteScrollView: UIScrollView {

    var scene: SKScene?


    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        scene?.touchesBegan(touches, withEvent: event)
    }

    override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
        scene?.touchesMoved(touches, withEvent: event)
    }

    override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
        scene?.touchesCancelled(touches, withEvent: event)
    }

    override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
        scene?.touchesEnded(touches, withEvent: event)
    }
}

然后您的场景需要查看触摸是否触及任何节点并将触摸适当地发送到这些节点。所以在你SKScene添加这个:

var nodesTouched: [AnyObject] = []

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    super.touchesBegan(touches, withEvent: event)

    let location = (touches.first as! UITouch).locationInNode(self)
    nodesTouched = nodesAtPoint(location)

    for node in nodesTouched as! [SKNode] {
        node.touchesBegan(touches, withEvent: event)
    }
}

override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
    super.touchesMoved(touches, withEvent: event)

    for node in nodesTouched as! [SKNode] {
        node.touchesMoved(touches, withEvent: event)
    }
}

override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
    super.touchesCancelled(touches, withEvent: event)
    for node in nodesTouched as! [SKNode] {
        node.touchesCancelled(touches, withEvent: event)
    }
}

override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
    super.touchesEnded(touches, withEvent: event)
    for node in nodesTouched as! [SKNode] {
        node.touchesEnded(touches, withEvent: event)
    }
}

请注意,这是针对单次触摸并且不能很好地处理错误,如果您想正确执行此操作,则需要在 if 语句中包含一些强制向下转换

我希望这对某人有所帮助,即使这个问题已经存在几个月了。

于 2015-05-03T16:08:23.163 回答