Mobile
 

iPad Development : The Dual-Action Color Popover (part 3) - Serving Two Masters

12/3/2011 4:31:34 PM

3. Serving Two Masters

Before we use this new controller from DudelViewController, we need to make two subclasses of the SelectColorController class, since DudelViewController uses the class of the currently active popover controller to determine exactly which controller it's dealing with.

NOTE

Purists may object to the creation of subclasses that don't have any behavior or data of their own, but then again, purists object to a lot of things. Being reality-based, we'll do it this way, both because it's simple and because it lets DudelViewController deal with all the popovers as consistently as possible.

Use the New File Assistant to create a new class. The assistant doesn't know about the SelectColorController class, so we need to use NSObject as the superclass and change it later. Name the class StrokeColorController, and give its .h and .m files the following contents:

//  StrokeColorController.h
#import <Foundation/Foundation.h>
#import "SelectColorController.h"
@interface StrokeColorController : SelectColorController {}
@end

// StrokeColorController.m
#import "StrokeColorController.h"
@implementation StrokeColorController
@end

Create another new class named FillColorController, and define it like this:

//  FillColorController.h
#import "SelectColorController.h"
@interface FillColorController : SelectColorController {}
@end

// FillColorController.m
#import "FillColorController.h"
@implementation FillColorController
@end

Now let's add support for both of these to DudelViewController in one fell swoop. Open DudelViewController.m, and start off adding these includes:

#import "StrokeColorController.h"
#import "FillColorController.h"
#import "ColorGrid.h"

Next, let's look at the code that will launch each of the font selectors. The two action methods are very similar, so instead of repeating a lot of code, we put most of it into a separate method, shown here:

// both of the color popover action methods call this method.
- (void)doPopoverSelectColorController:(SelectColorController*)scc sender:(id)sender {
[self setupNewPopoverControllerForViewController:scc];
scc.container = self.currentPopover;
self.currentPopover.popoverContentSize = scc.view.frame.size;

// these have to be set after the view is already loaded (which happened
// a couple of lines ago, thanks to scc.view...)
scc.colorGrid.columnCount = 3;
scc.colorGrid.rowCount = 4;
scc.colorGrid.colors = [NSArray arrayWithObjects:
[UIColor redColor],
[UIColor greenColor],
[UIColor blueColor],
[UIColor cyanColor],
[UIColor yellowColor],
[UIColor magentaColor],
[UIColor orangeColor],
[UIColor purpleColor],
[UIColor brownColor],
[UIColor whiteColor],
[UIColor lightGrayColor],
[UIColor blackColor],
nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(colorSelectionDone:) name:ColorSelectionDone object:scc];

[self.currentPopover presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
- (IBAction)popoverStrokeColor:(id)sender {
StrokeColorController *scc = [[[StrokeColorController alloc]
initWithNibName:@"SelectColorController" bundle:nil] autorelease];
scc.selectedColor = self.strokeColor;


[self doPopoverSelectColorController:scc sender:sender];
}
- (IBAction)popoverFillColor:(id)sender {
FillColorController *fcc = [[[FillColorController alloc]
initWithNibName:@"SelectColorController" bundle:nil] autorelease];
fcc.selectedColor = self.fillColor;
[self doPopoverSelectColorController:fcc sender:sender];
}

In each of those cases, our main controller is set up to listen for notifications from the color selector. Here's the method that will handle the notifications:

- (void)colorSelectionDone:(NSNotification *)notification {
SelectColorController *object = [notification object];
UIPopoverController *popoverController = object.container;
[popoverController dismissPopoverAnimated:YES];
[self handleDismissedPopoverController:popoverController];
}

Finally, we take care of the main popover dismissal handler. Add the bold lines to the following method, which will make us notice new values in the color selectors:

- (void)handleDismissedPopoverController:(UIPopoverController*)popoverController {
if ([popoverController.contentViewController isMemberOfClass:
[FontListController class]]) {
// this is the font list, grab the new selection
FontListController *flc = (FontListController *)
popoverController.contentViewController;
self.font = [UIFont fontWithName:flc.selectedFontName size:self.font.pointSize];
} else if ([popoverController.contentViewController isMemberOfClass:
[FontSizeController class]]) {
FontSizeController *fsc = (FontSizeController *)
popoverController.contentViewController;
self.font = fsc.font;
} else if ([popoverController.contentViewController isMemberOfClass:
[StrokeWidthController class]]) {
StrokeWidthController *swc = (StrokeWidthController *)
popoverController.contentViewController;
self.strokeWidth = swc.strokeWidth;
} else if ([popoverController.contentViewController isMemberOfClass:
[StrokeColorController class]]) {
StrokeColorController *scc = (StrokeColorController *)
popoverController.contentViewController;
self.strokeColor = scc.selectedColor;
} else if ([popoverController.contentViewController isMemberOfClass:
[FillColorController class]]) {
FillColorController *fcc = (FillColorController *)
popoverController.contentViewController;
self.fillColor = fcc.selectedColor;
}
self.currentPopover = nil;
}


You should now be able to build and run your app, and use the new color popovers to define stroke and fill colors for all of the tools.

With this functionality in place, we have all we need for a bare-bones vector-drawing app. No one's going to mistake this for Adobe Illustrator, but it's easy and functional enough for people to use for simple creations. Figure 3 shows an example of what you can create with Dudel.

Figure 3. Drawing with Dudel (Dave Wooldridge's creation)
 
Others
 
- iPad Development : The Dual-Action Color Popover (part 2) - Hooking Up the Grid
- iPad Development : The Dual-Action Color Popover (part 1) - Creating a Simple Color Grid
- XNA Game Studio 3.0 : Creating Fake 3-D - Creating Shadows Using Transparent Colors
- Android Application Development : ViewGroups (part 2) - ListView, ListActivity, ScrollView & TabHost
- Android Application Development : ViewGroups (part 1) - Gallery and GridView
- Java ME on Symbian OS : MIDP 2.0 Game API Core Concepts
- Java ME on Symbian OS : Building a Simple MIDP Game
- jQuery 1.3 : Compound effects & Creating custom animations
- jQuery 1.3 : Effects and speed
- Mobile Web Apps : Quick Wins (part 2) - Form Field Attributes
- Mobile Web Apps : Quick Wins (part 1) - Nifty Links
- iPhone Developer : Using Creative Popping Options
- iPhone Developer : Navigating Between View Controllers
- iOS SDK : Basic SQLite Database Manipulation (part 3) - SQLite Binding, Inserting, Updating, and Deleting
- iOS SDK : Basic SQLite Database Manipulation (part 2) - Select
- iOS SDK : Basic SQLite Database Manipulation (part 1) - Opening the Database, Statements, Preparing Statements, and Executing Statements
- The Anatomy of a Mobile Site : PRIMARY SITE CONTENT (part 3) - Forms
- The Anatomy of a Mobile Site : PRIMARY SITE CONTENT (part 2) - Embedding Images and Media
- The Anatomy of a Mobile Site : PRIMARY SITE CONTENT (part 1) - Text, Typography& Pagination
- iPad Does Not Show Up in iTunes & Synchronization Problems
 
 
Most View
 
- Adobe Flash Professional CS5 : Manipulating Symbols in 3D Space (part 1) - Controlling the camera view: Perspective and vanishing point
- Adobe Flash Professional CS5 : Manipulating Symbols in 3D Space (part 2) - Transforming symbols with the 3D Rotation tool
- Mobile Web Apps : Loading Pages (part 3) - Going Backwards
- Microsoft Dynamics AX 2009 : Design and Implementation Patterns (part 1) - Class-Level Patterns
- Introducing the iPhone SDK (part 5) - Programming Paradigms
- Beginning Android 3 : Set Up the Emulator
- Microsoft Excel 2010 : Analyzing Worksheet Data - Adding Data Validation to a Worksheet
- Microsoft Dynamic CRM 2011 : Resolving a Service Request Case
- Accessing PowerPoint on the Web and Mobile Devices (part 1) - Setting Up SkyDrive
- Microsoft Excel 2010 : Using Print Preview