3

First off, I have already seen and tried to implement the other answers to similar questions here, here and here. The problem is I started programming for iOS last year with Swift and (regrettably) I did not learn ObjC first (yes, it's now on my to-do list). ;-)

So please take a look and see if you might help me see my way thru this.

I can easily pinch to zoom the whole SKScene. I can also scale an SKSpiteNode up/down by using other UI Gestures (ie. swipes) and SKActions.

Based off this post I have applied the SKAction to the UIPinchGestureRecognizer and it works perfectly to zoom IN, but I cannot get it to zoom back OUT.

What am I missing?

Here is my code on a sample project:

class GameScene: SKScene {

var board = SKSpriteNode(color: SKColor.yellowColor(), size: CGSizeMake(200, 200))

func pinched(sender:UIPinchGestureRecognizer){
    println("pinched \(sender)")
    // the line below scales the entire scene
    //sender.view!.transform = CGAffineTransformScale(sender.view!.transform, sender.scale, sender.scale)
    sender.scale = 1.01

    // line below scales just the SKSpriteNode
    // But it has no effect unless I increase the scaling to >1
    var zoomBoard = SKAction.scaleBy(sender.scale, duration: 0)
    board.runAction(zoomBoard)
}

// line below scales just the SKSpriteNode
func swipedUp(sender:UISwipeGestureRecognizer){
    println("swiped up")
    var zoomBoard = SKAction.scaleBy(1.1, duration: 0)
    board.runAction(zoomBoard)
}

// I thought perhaps the line below would scale down the SKSpriteNode
// But it has no effect at all
func swipedDown(sender:UISwipeGestureRecognizer){
    println("swiped down")
    var zoomBoard = SKAction.scaleBy(0.9, duration: 0)
    board.runAction(zoomBoard)
}

override func didMoveToView(view: SKView) {

    self.addChild(board)

    let pinch:UIPinchGestureRecognizer = UIPinchGestureRecognizer(target: self, action: Selector("pinched:"))
    view.addGestureRecognizer(pinch)


    let swipeUp:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedUp:"))
    swipeUp.direction = .Up
    view.addGestureRecognizer(swipeUp)

    let swipeDown:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedDown:"))
    swipeDown.direction = .Down
    view.addGestureRecognizer(swipeDown)


}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    // should I be using this function instead?


}

Thanks to the help from @sangony I have gotten this working finally. I thought I'd post the working code in case anyone else would like to see it in Swift.

var board = SKSpriteNode(color: SKColor.yellowColor(), size: CGSizeMake(200, 200))

var previousScale = CGFloat(1.0)

func pinched(sender:UIPinchGestureRecognizer){
    if sender.scale > previousScale {
        previousScale = sender.scale
        if(board.size.height < 800) {
            var zoomIn = SKAction.scaleBy(1.05, duration:0)
            board.runAction(zoomIn)
        }
    }
    if sender.scale < previousScale {
        previousScale = sender.scale
        if(board.size.height > 200) {
            var zoomOut = SKAction.scaleBy(0.95, duration:0)
            board.runAction(zoomOut)
        }
    }
Community
  • 1
  • 1
Freedlun
  • 79
  • 10

1 Answers1

0

I tried your code (in Objective C) and got it to zoom in and out using pinch. I don't think there's anything wrong with your code but you are probably not taking into account the scale factors as they are placed on the ever changing sprite size.

You can easily zoom so far out or in that it requires multiple pinch gestures to get the node back to a manageable size. Instead of using the scale property directly for your zoom factor, I suggest you use a step process. You should also have max/min limits for your scale size.

To use the step process you create a CGFloat ivar previousScale to store the last scale value as to determine whether the current pinch is zooming in or out. You then compare the new passed sender.scale to the ivar and zoom in or out based on the comparison.

Apply min and max scale limits to stop scaling once they are reached.

The code below is in Obj-C but I'm sure you can get the gist of it:

First declare your ivar float float previousScale;

- (void)handlePinch:(UIPinchGestureRecognizer *)sender {

    NSLog(@"pinchScale:%f",sender.scale);

    if(sender.scale > previousScale) {
        previousScale = sender.scale;

        // only scale up if the node height is less than 200
        if(node0.size.height < 200) {
            // step up the scale factor by 0.05
            [node0 runAction:[SKAction scaleBy:1.05 duration:0]];
        }
    }

    if(sender.scale < previousScale) {
        previousScale = sender.scale;

        // only scale down if the node height is greater than 20
        if(node0.size.height > 20) {
            // step down the scale factor by 0.05
            [node0 runAction:[SKAction scaleBy:0.95 duration:0]];
        }
    }
}
sangony
  • 11,636
  • 4
  • 39
  • 55
  • What!? It works for you as is? Hmm... I just loaded it and tried it again on my iPad and when I pinch (move two fingers towards each other) it zooms IN like it should. But when I un-pinch (move two fingers away from each other) it still zooms IN. Could it be a bug? And thank you for the min/max scale, I had planned on adding that as well as zooming from the point of touch rather than the corner like currently. I'll try adapting your code and see what I get. Thanks!! – Freedlun Apr 10 '15 at 13:19
  • Is it possible that you subconsciously corrected it when you converted it ObjC?? ;-) Thus correcting my fault code. – Freedlun Apr 10 '15 at 13:33
  • @Freedlun - I just looked at your pinch code again and I see that you are hard coding the send.scale with the command "sender.scale = 1.01". So in effect you are disregarding the actual value being passed and setting it at 1.01 Take that line out and it should work. – sangony Apr 10 '15 at 13:56
  • Thank you so much! I overlooked that bit of code in all my attempts to get it right. Got it working with your code above as well, now I just need to work out how to get it zoom in from the point of contact. – Freedlun Apr 10 '15 at 23:34
  • @Freedlun - If my code answered your question, please check as answered. – sangony Apr 10 '15 at 23:40
  • Sorry, thought I had. – Freedlun Apr 11 '15 at 17:33