简体   繁体   English

SpriteKit自定义UIScrollView加速

[英]SpriteKit custom UIScrollView with acceleration

Basically I need to create a UIScrollView in my SpriteKit project but i'm having a lot of problem adding SKButtons (custom SKNode class for button management). 基本上我需要在我的SpriteKit项目中创建一个UIScrollView但是我在添加SKButtons(用于按钮管理的自定义SKNode类)时遇到了很多问题。 So I proceeded to create a scrollable SKNode with touch gesture but, obviously, this bar won't have the native UIScrollView acceleration: the feature I was looking for. 所以我开始创建一个带有触摸手势的可滚动SKNode,但很明显,这个栏不会有原生的UIScrollView加速:我正在寻找的功能。

So tried to overtake this problem by adding a native UIScrollView and catch every change of position, like this: 因此,尝试通过添加本机UIScrollView来取代此问题并捕获每个位置更改,如下所示:

在此输入图像描述

using this code: 使用此代码:

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

This works right but foolishly I forgot that if I add buttons, the touch gesture won't recognize the button's touch event! 这是正常的,但我很愚蠢地忘记了如果我添加按钮,触摸手势将无法识别按钮的触摸事件! (The UIScrollView has the priority). (UIScrollView具有优先级)。

Maybe is just a stupid question but I don't really know how to figure it out. 也许这只是一个愚蠢的问题,但我真的不知道如何解决这个问题。 Maybe programming my own acceleration methods? 也许编程我自己的加速方法?

One possible solution would be to add tap gesture to scene: 一种可能的解决方案是向场景添加点击手势:

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)
    }
}

I think I came up with a solution to handle touches. 我想我想出了一个处理触摸的解决方案。 Since the UIScrollView eats all the touches to allow it to scroll you need to pass them to the SKScene . 由于UIScrollView所有触摸来允许它滚动,因此需要将它们传递给SKScene You can do that by subclassing UIScrollView : 你可以通过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)
    }
}

Then your scene needs to see if the touch hits any nodes and appropriately send the touches to those nodes. 然后你的场景需要看看触摸是否触及任何节点并适当地将触摸发送到那些节点。 So in your SKScene add this: 所以在你的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)
    }
}

Note this is for single touches and does not handle errors well, you'll need to wrap some of the forced down casting in if statements if you want to do this properly 请注意,这是针对单个触摸并且不能很好地处理错误,如果要正确执行此操作,则需要在if语句中包含一些强制向下转换

I hope this helps someone even though the question is months old. 我希望这可以帮助某人,即使问题是几个月前。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM