[아이폰 앱 개발] iPad for iPhone Developers 101: UIPopoverController Tutorial

iPad for iPhone Developers 101: UIPopoverController Tutorial

http://www.raywenderlich.com/1056/ipad-for-iphone-developers-101-uipopovercontroller-tutorial

This is the second part of a three part series to help get iPhone Developers up-to-speed with iPad development by focusing on three of the most interesting new classes (at least to me): UISplitView, UIPopoverController, and Custom Input Views.

In the first part of the series, we made an app with a split view that displays a list of monsters on the left side, and details on the selected monster on the right side.

In this part, we’re going to try out popovers view with a simple example: we’ll add a popover to let the user select from a list of colors to change the color of the monster’s name.

We’ll start out with where we left off the project last time, so grab a copy if you don’t have it already.

Creating our Color Picker

Let’s start by creating the view that we’ll use to let the user pick between a list of colors. We’ll make this a simple table view with a list of color names.

So go to “File\New File…”, pick “UIViewController subclass”, and make sure “Targeted for iPad” and “UITableViewController subclass” are checked but “With XIB for user interface” is NOT checked, and click Next. Name the class ColorPickerController, and click Finish.

Then replace ColorPickerController.h with the following:


@protocol ColorPickerDelegate
- (void)colorSelected:(NSString *)color;
@end
 
 
@interface ColorPickerController : UITableViewController {
    NSMutableArray *_colors;
    id<ColorPickerDelegate> _delegate;
}
 
@property (nonatomic, retain) NSMutableArray *colors;
@property (nonatomic, assign) id<ColorPickerDelegate> delegate;
 
@end

Here we declare a delegate so that this class can notify another class when a user selects a color. We then declare two variables/properties: one for the list of colors to display, and one to store the delegate itself.

Then make the following changes to ColorPickerController.m:


// Under @implementation
@synthesize colors = _colors;
@synthesize delegate = _delegate;
 
// Add viewDidLoad like the following:
- (void)viewDidLoad {
    [super viewDidLoad];
    self.clearsSelectionOnViewWillAppear = NO;
    self.contentSizeForViewInPopover = CGSizeMake(150.0, 140.0);
    self.colors = [NSMutableArray array];
    [_colors addObject:@"Red"];
    [_colors addObject:@"Green"];
    [_colors addObject:@"Blue"];
}
 
// in numberOfSectionsInTableView:
return 1;
 
// in numberOfRowsInSection:
return [_colors count];
 
// In cellForRowAtIndexPath, under configure the cell:
NSString *color = [_colors objectAtIndex:indexPath.row];
cell.textLabel.text = color;
 
// In didSelectRowAtIndexPath:
if (_delegate != nil) {
    NSString *color = [_colors objectAtIndex:indexPath.row];
    [_delegate colorSelected:color];
}
 
// In dealloc
self.colors = nil;
self.delegate = nil;

Most of this should be normal table view stuff except for the following line:


self.contentSizeForViewInPopover = CGSizeMake(150.0, 140.0);

This line sets the size of how large the popover should be when it is displayed. If you do not add this line, by default the popover will be the entire height of the screen (which is usually too large).

Displaying the Picker

Believe it or not, that was the hardest part. Now to display the picker, all we need to do is add a button to our toolbar, and a little bit of code to display it and handle the selection.

So first, let’s add the button. Open up RightViewController.xib and add a Bar Button Item to the toolbar. Set the title of the button “Set Color”.

Now let’s declare a method for the button to trigger in RightViewController.h and declare a few variables we’ll need in a minute:


// Up top, under #import
#import "ColorPickerController.h"
 
// Modfiy class declaration
@interface RightViewController : UIViewController <MonsterSelectionDelegate,  
    UISplitViewControllerDelegate, ColorPickerDelegate> {
 
// Inside class
ColorPickerController *_colorPicker;
UIPopoverController *_colorPickerPopover;
 
// In property section
@property (nonatomic, retain) ColorPickerController *colorPicker;
@property (nonatomic, retain) UIPopoverController *colorPickerPopover;
 
- (IBAction)setColorButtonTapped:(id)sender;

Before we forget, go ahead and connect the action method to the Bar Button Item in Interface Builder by control-dragging from the Bar Button Item to File’s Owner and connecting to the “setColorButtonTapped” outlet.

Then let’s finish by making the required changes to RightViewController.m:


// In synthesize section
@synthesize colorPicker = _colorPicker;
@synthesize colorPickerPopover = _colorPickerPopover;
 
// In dealloc
self.colorPicker = nil;
self.colorPickerPopover = nil;
 
// Add to end of file
- (void)colorSelected:(NSString *)color {
    if ([color compare:@"Red"] == NSOrderedSame) {
        _nameLabel.textColor = [UIColor redColor];
    } else if ([color compare:@"Green"] == NSOrderedSame) {
        _nameLabel.textColor = [UIColor greenColor];
    } else if ([color compare:@"Blue"] == NSOrderedSame){
        _nameLabel.textColor = [UIColor blueColor];
    }
    [self.colorPickerPopover dismissPopoverAnimated:YES];
}
 
- (IBAction)setColorButtonTapped:(id)sender {
    if (_colorPicker == nil) {
        self.colorPicker = [[[ColorPickerController alloc] 
            initWithStyle:UITableViewStylePlain] autorelease];
        _colorPicker.delegate = self;
        self.colorPickerPopover = [[[UIPopoverController alloc] 
            initWithContentViewController:_colorPicker] autorelease];               
    }
    [self.colorPickerPopover presentPopoverFromBarButtonItem:sender 
        permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}

Ok let’s explain this a bit. All popovers are is a “wrapper” around an existing view controller that “floats” it in a certain spot and possibly displays an arrow showing what the popover is related to. You can see this in setColorButtonTapped – we create our color picker, and then wrap it with a popover controller.

Then we call a method on the popover controller to display it in the view. We use the helper function presentPopoverFromBarButtonItem to display the popover.

When the user is done, they can tap anywhere outside the popover to dismiss it automatically. However if they select a color, we also want it to be dismissed, so we call the dismissPopoverAnimated method to get rid of the popover on-demand (as well as setting the color appropriately).

And that’s it! Compile and run and when you tap the “Set Color” bar button item, you should see a popover like the following that changes the label color:

You will find yourself using popovers quite a bit in places where users need to edit a field or toggle a setting, rather than the iPhone style where you navigate to the next level in a UINavigationController. They call this “flattening the hierarchy” in the iPad docs.

Show Me the Code!

Here’s a copy of all of the code we’ve developed so far.

Check out the next part of the series, where we cover how to use custom input views on the iPad!

Posted by 오늘마감

티스토리 툴바