To keep the font selector simple, we'll have the size
selection as a separate operation, in its own popover. The GUI for the
font size selector will consist of a slider, a label showing the
slider's value, and a text view showing a preview of the chosen font at
the chosen size. As the user operates the slider, the preview
immediately reflects the slider's value. Figure 1 shows the GUI in action.
Unlike the font list, the
font size popover shouldn't go away as soon as the user touches it—that
would be a pretty surprising response from touching a slider. That means
that the interaction between DudelViewController
and this new popover will be a little simpler than it was for the font
list, since the font size popover will never need to be explicitly
dismissed in our code. We'll rely on the system to dismiss it when the
user clicks outside it.
1. Creating the GUI
In Xcode, use the New File Assistant to make a new Cocoa Touch class. Select UIViewController as its superclass, and configure the check boxes to target iPad and create an .xib file, but to not make it a subclass of UITableViewController. Name the new class FontSizeController.
Start by editing FontSizeController.h,
which will contain outlets for each GUI object we need to interact
with, an instance variable containing the current chosen font, and an
action method for the slider to call. Here's the entire content of the
file:
// FontSizeController.h
#import <UIKit/UIKit.h>
@interface FontSizeController : UIViewController {
IBOutlet UITextView *textView;
IBOutlet UISlider *slider;
IBOutlet UILabel *label;
UIFont *font;
}
@property (retain, nonatomic) UIFont *font;
- (void)takeIntValueFrom:(id)sender;
@end
Now open FontSizeController.xib
in Interface Builder. The first thing you'll notice is that the default
view contained within is the size of the entire iPad screen. That's way
too big for our purposes! It's also showing a black status bar at the
top, as if it were a full-screen view.
Select the view, and use the
attribute inspector to set the Status Bar value to Unspecified. Then
use the size inspector to set its size to 320 by 320. You actually need
to do these two steps in that order, since if the Status Bar value is
set to Black, Interface Builder wants to treat that view as a
full-screen view, and won't let you change its size.
NOTE
Apple's documentation says that the minimum width for a popover is 320 pixels.
Now use the Library to grab a UITextView, a UISlider, and a UILabel, and put them each into the view, laid out something like what you saw in Figure 6-4.
In my version, I've broken up the monotony of the white background by
setting the main view's background color to light gray. You can skip
this step if you like, or use a different background color.
Next, connect each outlet from
File's Owner to one of the GUI objects by control-clicking that icon,
dragging to a GUI object, and selecting the appropriate outlet from the
list that appears. Then connect the slider's target and action by
control-clicking the slider, dragging to File's Owner, and selecting the
takeIntValueFrom: method.
Select the UITextView
you created earlier. This contains some "Lorem ipsum" text by default,
which is fine for our purposes, so leave that bit alone. However, we
don't want users interacting with this text view, so use the attribute
inspector to turn off the Editable check box, as well as all of the
check box options that affect scrolling behavior.
Finally select the slider, and
set its minimum and maximum values to 1 and 96, respectively. The GUI is
now complete! Save your work, and go back to Xcode.
2. Making It Work
Now it's time for the FontListController
implementation, which is shown here in an abbreviated form after
deleting extra comments and unneeded overrides from the template:
// FontSizeController.m
#import "FontSizeController.h"
@implementation FontSizeController
@synthesize font;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
textView.font = self.font;
NSInteger i = self.font.pointSize;
label.text = [NSString stringWithFormat:@"%d", i];
slider.value = i;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation {
// Overridden to allow any orientation.
return YES;
}
- (void)dealloc {
self.font = nil;
[super dealloc];
}
- (void)takeIntValueFrom:(id)sender {
NSInteger size = ((UISlider *)sender).value;
self.font = [self.font fontWithSize:size];
textView.font = self.font;
label.text = [NSString stringWithFormat:@"%d", size];
}
@end
As you can see, this class is quite simple. It basically just responds to the user dragging the slider by modifying the font property and updating the display.
Now all that's left to do is integrate this new class with the view controller. Switch back to DudelViewController.m, where we have a few changes to make. Add this near the top:
#import "FontSizeController.h"
Then update the handleDismissedPopoverController: method like this:
- (void)handleDismissedPopoverCo2ntroller:(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;
}
self.currentPopover = nil;
}
After that, we just need to fill in the popoverFontSize: method, like this:
- (IBAction)popoverFontSize:(id)sender {
FontSizeController *fsc = [[[FontSizeController alloc] initWithNibName:nil bundle:nil]
autorelease];
fsc.font = self.font;
[self setupNewPopoverControllerForViewController:fsc];
self.currentPopover.popoverContentSize = fsc.view.frame.size;
[self.currentPopover presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
The one new thing we're doing in this method is setting the popoverContentSize property on the currentPopover. If we didn't do this, the popup would automatically fill the maximum height of the screen.
With that in place, we're finished with the font size selection popup. Build and run the app, and you should see something like Figure 2. Notice that since this popover knows about the complete UIFont object that is currently set, not just the size, we can display the font preview with the correct font and size.
Now we have pretty good
control over the fonts we're using for the Text tool. This is still far
from a word processor or page layout app, but it's a pretty decent
start, especially considering how little code we've written!