Differences

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

Link to this comparison view

manual_v1:adding_uikit_elements_on_top_of_sparrow [2013/03/05 10:19]
127.0.0.1 external edit
manual_v1:adding_uikit_elements_on_top_of_sparrow [2013/05/25 12:43] (current)
daniel [Adding UIKit Elements on top of Sparrow]
Line 1: Line 1:
 +====== Adding UIKit Elements on top of Sparrow ======
 +
 +//The following article assumes that your game is based on the Scaffold project that comes with Sparrow 1.3.//
 +
 +The scaffold project contains an additional ''​UIView''​ object directly above Sparrow'​s ''​SPView''​. Just like your Sparrow content, that view is automatically rotated according to the device orientation and your app settings. It is thus the perfect place to put any UIKit content.
 +
 +{{ :​manual:​scaffold_layers.png?​nolink |}}
 +
 +In this tutorial, we will add a simple ''​UISwitch''​ object to the overlay view. 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 app looks like in its unmodified state:
 +
 +{{ :​manual:​scaffold_startup_unmodified.png?​nolink&​width=200px |}}
 +
 +===== Adding the Switch =====
 +
 +The world of Sparrow and the world of UIKit are separated. As the image at the top of this article shows, their content is placed within 2 different layers: ​
 +
 +  * a ''​UIView''​ object for UIKit objects and 
 +  * an ''​SPView''​ object for Sparrow content. ​
 + 
 +The ''​ViewController''​ class that is part of the scaffold project can access both of those worlds.
 +
 +Currently, when you touch the egg, a sound is played. Let's say we want to show the UIKit switch instead. To do this, we update the event handler and dispatch a custom event instead:
 +
 +<code objc>
 +- (void)onEggTouched:​(SPTouchEvent *)event
 +{
 +    NSSet *touches = [event touchesWithTarget:​self andPhase:​SPTouchPhaseEnded];​
 +    if ([touches anyObject])
 +    {
 +        SPEvent *event = [SPEvent eventWithType:​@"​eggTouched"​ bubbles:​YES];​
 +        [self dispatchEvent:​event];​
 +
 +    }
 +}
 +</​code>​
 +
 +Why do we dispatch an event here? Because this is the only way we can communicate with the ''​ViewController''​ class. Remember: we're on the Sparrow layer here!
 +
 +The ''​ViewController''​ can now listen to this event. Open up ''​ViewController.m''​ and add an appropriate event listener in its ''​init''​-method:​
 +
 +<code objc>
 +- (id)initWithSparrowView:​(SPView *)sparrowView
 +{
 +    if ((self = [super init]))
 +    {
 +        // ...
 +        ​
 +        [sparrowView.stage addEventListener:​@selector(showSwitch:​) atObject:​self
 +                                    forType:​@"​eggTouched"​];​
 +    }
 +    return self;
 +}
 +</​code>​
 +
 +Note that the stage is a property of the Sparrow view, and that's our connection to the Sparrow world. The event we dispatched above will bubble up to the stage, thus we can listen to the event through the stage.
 +
 +We're going to need an event listener, of course. Add the following methods to the ''​ViewController''​ class:
 +
 +<code objc>
 +- (void)showSwitch:​(SPEvent *)event
 +{
 +    if (!mSwitch)
 +    {
 +        mSwitch = [[UISwitch alloc] initWithFrame:​CGRectMake(15,​ 15, 0, 0)];
 +        [mSwitch addTarget:​self action:​@selector(onSwitchValueChanged) ​
 +          forControlEvents:​UIControlEventValueChanged];​
 +        ​
 +        [self.view addSubview:​mSwitch];​
 +        [mSwitch release];
 +    }
 +}
 +
 +- (void)onSwitchValueChanged
 +{
 +    NSLog(@"​value:​ %d", mSwitch.isOn);​
 +}
 +</​code>​
 +
 +Here, we create a switch and display it at the top left of the screen. Furthermore,​ we log a message every time the switch changes its value.
 +
 +That ''​mSwitch''​ object needs to be declared, of course. Add its declaration to the ''​ViewController.h''​ file.
 +
 +<code objc>
 +@interface ViewController : UIViewController
 +{
 +  @private
 +    SPView *mSparrowView;​
 +    UISwitch *mSwitch; // <-- here
 +}
 +</​code>​
 +
 +And add the function declaration to the same file:
 +
 +<code objc>
 +- (id)initWithSparrowView:​(SPView *)sparrowView;​
 +- (void)showSwitch:​(SPEvent *)event; ​   // <--- here
 +</​code>​
 +
 +Let's start up the project and see what happens. After tapping the egg, the switch should appear, and Xcode should log 1s and 0s when its state changes.
 +
 +{{ :​manual:​scaffold_with_switch.png?​165 |}}
 +
 +===== Communicating with our Game =====
 +
 +The previous step showed us how to send a message from Sparrow to the ''​ViewController''​. Now we want to go the other direction: the ''​ViewController''​ should somehow communicate with our ''​Game''​ class and change the color of the egg.
 +
 +First, we will update the method that is called when the switch changes its value:
 +
 +<code objc>
 +- (void)onSwitchValueChanged
 +{
 +    Game *game = (Game *)[mSparrowView.stage childAtIndex:​0];​
 +    [game colorizeEgg:​mSwitch.isOn];​
 +}
 +</​code>​
 +
 +Let's see what is going on here:
 +
 +  * We know that our stage is really the ''​GameController''​ class, and that the ''​GameController''​ has exactly one child: the ''​Game''​. So we can access it like shown above. (If that confuses you: it's like that simply because the scaffold project is set up like that. Just trust me: the line above let's you access the ''​Game'',​ period.)
 +  * Now that we can access the game, we can call any method on it. Here, we colorize it.
 +
 +The ''​colorizeEgg:''​ method does not exist yet, though. Let's create it!
 +
 +<code objc>
 +// add a new method declaration in the file '​Game.h':​
 +- (void)colorizeEgg:​(BOOL)colorize;​
 +
 +// then add the method in the class implementation,​ '​Game.m':​
 +- (void)colorizeEgg:​(BOOL)colorize
 +{
 +    SPImage *egg = (SPImage *)[self childAtIndex:​1];​
 +    egg.color = colorize ? SP_RED : SP_WHITE;
 +}
 +</​code>​
 +
 +(It would have been cleaner to save the egg object as a member variable instead of accessing the child at index '​1',​ but I'll leave that as an exercise for you ;-) ).
 +
 +That should be it! Indeed, we have succeeded in communicating up from the ''​ViewController''​ class to the ''​Game''​. If you don't believe me, start up the project, tap the egg, and then activate the switch! ​
 +
 +{{ :​manual:​scaffold_active_switch.png?​165 |}}
 +
 +Cool, isn't it? Now you can add any other UIKit element just like that.
 +
 +
  
  manual_v1/adding_uikit_elements_on_top_of_sparrow.txt · Last modified: 2013/05/25 12:43 by daniel
 
Powered by DokuWiki