2. The Back End
Now it's time to implement the portions of DudelViewController that will fire up the FontListController, dismiss its popover when the user makes a selection, and grab the selected value. Start with an import:
#import "FontListController.h"
Then fill in this previously empty method:
- (IBAction)popoverFontName:(id)sender {
FontListController *flc = [[[FontListController alloc]
initWithStyle:UITableViewStylePlain] autorelease];
flc.selectedFontName = self.font.fontName;
[self setupNewPopoverControllerForViewController:flc];
flc.container = self.currentPopover;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(fontListControllerDidSelect:)
name:FontListControllerDidSelect
object:flc];
[self.currentPopover presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
This method creates and configures a FontListController instance. Part of the configuration involves calling a method named setupNewPopoverControllerForViewController:
(which we're going to create in just a minute). It also sets us up as
an observer for a notification, which will tell us that the user
selected something, and then displays a popover.
What's not really clear here is the final line, which contains self.currentPopover.
We haven't set that, have we? Well, the following auxiliary method
does! Insert this method somewhere above all the popover action methods:
- (void)setupNewPopoverControllerForViewController:(UIViewController *)vc {
if (self.currentPopover) {
[self.currentPopover dismissPopoverAnimated:YES];
[self handleDismissedPopoverController:self.currentPopover];
}
self.currentPopover = [[[UIPopoverController alloc] initWithContentViewController:vc]
autorelease];
self.currentPopover.delegate = self;
}
We'll use this method every
time we're going to present a popover. By doing so, we save a few lines
in each popover action method, and also ensure that we're doing things
the same way each time. Now, I'm not going to pretend that this separate
method sprang from my forehead in one piece.
Any time you find
yourself doing cut-and-paste coding, consider chunking things off into
separate methods, because someone is probably going to revisit your code
someday. The mind you save may be your own.
|
|
So now we have code in place
to fire up the popover, but we still need to handle the user selecting
something. Begin by creating a method to be called when the notification
we're observing is triggered:
- (void)fontListControllerDidSelect:(NSNotification *)notification {
FontListController *flc = [notification object];
UIPopoverController *popoverController = flc.container;
[popoverController dismissPopoverAnimated:YES];
[self handleDismissedPopoverController:popoverController];
self.currentPopover = nil;
}
Here, you see the reason for putting the container property in FontListController. After the user makes a selection, FontListController shoots off a notification. DudelViewController
picks it up, and uses the container property to dismiss the popover.
This method also calls the main handler for all our popovers, which you
should now revise to this:
- (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];
}
self.currentPopover = nil;
}
This is where the selection
in the popover finally ends up having an effect. The font is now set
according to what the user picked.
You should now be able to build
and run the app, and then touch the font list button in the toolbar to
see something like the popup shown in Figure 2.
Try selecting a different
font, and then using the Text tool to create some text. Neat! You now
have the full complement of fonts included with the iPad at your
disposal. You're still stuck with just one size, so let's tackle that
next.