Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
manual:adding_uikit_elements_on_top_of_sparrow [2014/08/06 13:41] – [Adding UIKit Elements on top of Sparrow] 178.219.160.178manual:adding_uikit_elements_on_top_of_sparrow [2014/08/25 08:32] (current) – Removed vandalism ... daniel
Line 1: Line 1:
 +====== Adding UIKit Elements on top of Sparrow ======
  
 +Sparrow renders all its contents directly into the ''view'' object of its ''SPViewController''. Since the ''view'' is a normal ''UIView'' object, you can add any conventional UIKit view objects on top of Sparrow. The UIKit objects will always be drawn on top of the Sparrow elements, though; you cannot place Sparrow elements on top of UIKit elements.
 +
 +{{ :manual:scaffold_layers_v2.png?width=450px |}}
 +
 +===== Mission Objective =====
 +
 +In this tutorial, we will add a simple ''UISwitch'' object on top of Sparrow. Changing the state of the switch will then affect the color of an object within the Sparrow display tree. 
 +
 +While the sample itself does not look super-useful, it will show everything you need to know to be able to combine UIKit and Sparrow elements in interesting ways.
 +
 +This is how the scaffold app looks like in its original state:
 +
 +{{ :manual:scaffold_startup_unmodified.png?nolink&width=165 |}}
 +
 +===== Adding the Switch =====
 +
 +The unmodified version of the Scaffold project plays a sound when you touch the bird. Let's say we want to show the UIKit switch instead. To do this, we add a new method call to the event handler.
 +
 +<code objc>
 +- (void)onImageTouched:(SPTouchEvent *)event
 +{
 +    NSSet *touches = [event touchesWithTarget:self andPhase:SPTouchPhaseEnded];
 +    if ([touches anyObject])
 +    {
 +        [self showSwitch];
 +    }
 +}
 +</code>
 +
 +The ''showSwitch'' method is responsible for adding that switch. For this to happen, add the member variable ''_switch'' to the class, and implement the ''showSwitch'' method like this:
 +
 +<code objc>
 +@implementation Game
 +{
 +    SPSprite *_contents;
 +    UISwitch *_switch; // <- Add the member variable here
 +}
 +
 +- (void)showSwitch
 +{
 +    if (!_switch)
 +    {
 +        _switch = [[UISwitch alloc] initWithFrame:CGRectMake(15, 15, 0, 0)];
 +        [_switch addTarget:self action:@selector(onSwitchValueChanged)
 +                 forControlEvents:UIControlEventValueChanged];
 +                 
 +        [Sparrow.currentController.view addSubview:_switch];
 +    }
 +}
 +
 +- (void)onSwitchValueChanged
 +{
 +    NSLog(@"switch value: %d", _switch.isOn);
 +}
 +</code>
 +
 +This is where it gets interesting! Creating the ''UISwitch'' is straight-forward; just init the class and add a UIKit-style event handler.
 +
 +But how do we get access to the basic UIKit view object? In Sparrow 2, you can access that object from anywhere in your code like this:
 +
 +<code objc>
 +SPViewController *viewController = Sparrow.currentController;
 +UIView *view = currentController.view;
 +</code>
 +
 +The ''currentController'' method of the ''Sparrow'' class always points to the view controller you created in the Application delegate. And that controller contains a reference to the ''UIView'' object it renders into. Thus, you can easily access that view from anywhere in your game with the one-liner we're using in the ''showSwitch'' method.
 +
 +Now let's start up the project and see what happens. After tapping the bird, the switch should appear, and Xcode should log 1s and 0s when its state changes.
 +
 +{{ :manual:scaffold_with_switch.png?165 |}}
 +
 +===== Updating the Bird =====
 +
 +To make it a little more interesting, we modify the event handler so it changes the color of the bird.
 +
 +<code objc>
 +- (void)onSwitchValueChanged
 +{
 +    NSLog(@"value: %d", _switch.isOn);
 +    
 +    SPImage *bird = (SPImage *)[_contents childAtIndex:2];
 +    bird.color = _switch.isOn ? SP_RED : SP_WHITE;
 +}
 +</code>
 +
 +(It would have been cleaner to save the bird object as a member variable instead of accessing the child at index '2', but I'll leave that as an exercise for you ;-) ).
 +
 +{{ :manual:scaffold_active_switch.png?165 |}}
 +
 +That should be it! You successfully added an UIKit object on top of Sparrow and are using it to modify a Sparrow display object! Cool, isn't it? Now you can add any other UIKit element just like that.
 +
 +===== Universal Apps =====
 +
 +There's one more thing you need to take care of. If you are developing a universal application with the ''doubleOnPad:'' strategy of Sparrow, the coordinate system of UIKit won't be the same as that of Sparrow. Remember, Sparrow will double the content scale factor in that case (it's called ''doubleOnPad:'' for a reason), but UIKit doesn't know about that.
 +
 +For this reason, you have to multiply the coordinates of your UIKit objects by a certain factor; on the iPad (both retina and non-retina), that factor will be ''2.0''.
 +
 +<note idea>
 +To find out the required multiplication factor at runtime, you can simply divide "Sparrow.contentScaleFactor" by \\
 +"Sparrow.currentController.view.contentScaleFactor".
 +</note>
 +
 +Also note that some standard interface elements (e.g. switches) have a fixed size and should not be scaled. You have to take that into account when you place those objects on the screen.
 +
 +----
 +
 +//Continue to [[Dynamic Textures]]//
 
 
Powered by DokuWiki