iOS7 Custom Transitions

iOS7 Custom Transitions
iOS7 Custom Transitions

iOS7 Series –Custom Transitions

There is a hierarchy of actors you need to visualize here.  It goes a little something like:

  1. A TransitioningDelegate
  2. An AnimatedTransitioning
  3. A ContextTransitioning

The VC you start out with and that will call the transition will adopt the first protocol, the TransitioningDelegate Protocol.  The purpose of doing so is to obtain the authority to manage the entire transition process.

You will then create a Transitioning class which we can call the Transition Manager.  This class will adopt the AnimatedTransitioning protocol.  The purpose of this protocol is to animate the transition.

The Transition Manager class receives all the necessary information from the Transitioning Context (a protocol adopted by a class you wont really see) and it sends that info to the TransitioningDelegate in order for it to call the shots.

The process itself is quite simple.  We create a Transition Manager class, which adopts the AnimatedTransitioning protocol as stated above.  Then we instantiate this class and call its methods from our initial view controller, who has adopted the TransitioningDelegate protocol in order to call the shots.  Voila, our VC calls the transition for us.

So create a subclass of NSObject and call it what you wish, I called it PinRotatingTransitionManager.  Of course make it adopt the AnimatedTransitioning protocol like so:

<UIViewControllerAnimatedTransitioning>

There are 2 methods you must implement in order to adopt this protocol.  The first one is:

//Define the transition duration

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{

return 1.0;

}

As you can see this simply states how long the transition will last.  It returns a value of type NSTimeInterval and takes in the transition context.

The second method is for describing the animation and it’s a bit long so let’s go one step at a time:

//1. Get current state

UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

CGRect sourceRect = [transitionContext initialFrameForViewController:fromVC];

First we get some values for the current state; who is our fromVC, who is our toVC and what is the relevant frame of our current, fromVC.  Remember we are transitioning between two vcs.  The one we are in is called the fromVC or initialVC or if you prefer to keep the original iOS lingo, our sourceVC.  The second one is called our toVC or finalVC or destinationVC.

We need to get a reference to both of them (basically to say THIS vc will do this and THAT vc will do that!).  And of course we need to know the frame we are starting from.

//2.Settings for the fromVC ……………………….

CGAffineTransform rotation;

rotation = CGAffineTransformMakeRotation(M_PI);

fromVC.view.frame = sourceRect;

fromVC.view.layer.anchorPoint = CGPointMake(0.5, 0.0);

fromVC.view.layer.position = CGPointMake(160.0, 0);

We create a rotation transform which will rotate anything by M_PI.  Then we set our fromVC frame to the sourceRect, we define an anchor point for it and a position for it.

//3.Insert the toVC view………………………

UIView *container = [transitionContext containerView];

[container insertSubview:toVC.view belowSubview:fromVC.view];

CGPoint final_toVC_Center = toVC.view.center;

Now we need to do something quite important…get a container view to put everything into in order to run the transition.  To that container view we must add the toVC, because the fromVC is already added for us.

//4.Insert the toVC view………………………

toVC.view.center = CGPointMake(-sourceRect.size.width, sourceRect.size.height);

toVC.view.transform = CGAffineTransformMakeRotation(M_PI/2);

Now we set the toVC’s center point and apply the transform created.

And finally we perform the animation:

//5. Animate..

[UIView animateWithDuration:1.0

delay:0.0

usingSpringWithDamping:.8

initialSpringVelocity:6.0

options:UIViewAnimationOptionCurveEaseIn

animations:^{

//Setup final params of the views

fromVC.view.transform = rotation;

toVC.view.center = final_toVC_Center;

toVC.view.transform = CGAffineTransformMakeRotation(0);

} completion:^(BOOL finished) {

//When done call completeTransition

[transitionContext completeTransition:YES];

}];

This is quite simple.  We define some parameters for the animation and call a block which applies the rotation and center etc.  Once complete we call completeTransition which is mandatory.

Now run your app and you should have a very nice transition where the fromVC slides left and the toVC rotates down into place.

 

Neat huh!

Creating a Menu in SpriteKit

SpriteKit Menu by Santiapps.com Marcio Valenzuela
SpriteKit Menu

Cocos2d has a easy to use CCMenu object to which you add CCMenuItems.  In SpriteKit however, you are back to UIKit objects.  This doesn’t not mean its more complicated, its just different :-).  You will need to create a UIControl such as a button or you can use SpriteKit’s SKNode to create the visual object onscreen:

SKLabelNode*  someNode = [SKLabelNode labelNodeWithFontNamed:@”Chalkduster”];
[someNode setText:@”Play Game”];
[someNode setPosition:CGPointMake(CGRectGetMidX(self.frame)+5,CGRectGetMidY(self.frame)-40)];
[self addChild: someNode];

Now you simply connect the object action to some event like so:

for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];

if ([someNode containsPoint:location]) {
SKTransition* present = [SKTransition revealWithDirection:SKTransitionDirectionDown duration:1];
GameScene* gameScene = [[GameScene alloc] initWithSize:CGSizeMake(1024, 768)];
[self.scene.view presentScene: someNode transition:present];

}
}

Voila!  You are DONE!

Swift Tutorial II

Ok so in the first tutorial we covered let, which is the keyword for defining constants.

let thisBeAConstant = 3.141

Now we are going to cover variables, which use the var keyword like so:

var thisVariable = time

Notice 2 things about Swift:

1) We don’t use ; at the end of a line.  That’s just weird 🙂

2) We don’t have to specify the type.  The type is inferred by whatever value you pass in, so:

var someString = “this is a string”

var someInteger = 5

So Swift is kinda smart.  Now let’s meet some old friends “Hao jiu bu juan”

ARRAYS

var energies = [“solar”“wind”“fossil”, “this is a mixed array”, 39]

var energies:String[] = [“solar”“wind”“this is a string array”]

And of course we can perform some basic operations such as:

READ

var item1 = energies[0]   // “solar”

INSERT

energies.insert(“hydro”, atIndex: 2)

MODIFY

energies[3] = “geothermal”

APPEND

energies.append(“nuclear”)

or

energies += “nuclear”

COMBINE

energies += [“biomass”“hamster”]

COUNT

var lengthofArray = energies.count

LOGIC

var arrayIsEmpty = energies.isEmpty

REMOVE

energies.removeAtIndex(3)
energies.removeLast()
energies.removeAll(keepCapacity: true)
MUTATE
If we used let energies, then our array is immutable, vs if we used var energies which means its mutable.
Easy as pie.
DICTIONARIES

var energies = [

    “Solar”“Thermal”,
    “Photovoltaic” : “Grid”,
    “Nuclear” : “Dangerous”
]
Here our keys are Solar, Photovoltaic & Nuclear.  These keys can be strings or numeric values such as integers.
Once again we can:
READ
let cheapestSolarEnergy = energies[“Solar”]
COUNT
var energiesCount = energies.count
MODIFY
energies[“Solar”] = “PV”
REMOVE
energies[“Nuclear”] = nil;
INSERT
energies[“Geo”] = “Thermal”
and of course the value of a key can be an array or another dictionary:

var typesOfEnergy =

[
    platforms[“Solar”]: [“Thermal”“PV”“GridTied”],
    platforms[“Wind”]: [“Autonomous”“GridTied”],
    platforms[“Nuclear”] : [“Fusion”“Fission”,“Meltdown”]
]
and we would read it:
var type1 = typesOfEnergy[“Solar”][0]
See you next time! 🙂