blog.JNL

[iPad] Tutorial: Creating a PopoverController [updated]

by Jannis on Apr.03, 2010, under iPad development

This tutorial explains what PopoverControllers are and how you can use them to create Popover’s in your iPad application. To be able to follow this tutorial, you’ll need the iPhone OS 3.2 SDK. Older versions for the iPhone itself cannot be used to create Popovers.

Popovers, what?

A Popover is a ‘popup’ view displayed on top of your regular iPad application interface. In this view, you can do whatever you like, such as providing the user with options or displaying additional functionality, usually related to the object you tapped on that triggers the popover. The main advantage of popovers is that they show up on the same screen, instead of replacing it like on the iPhone or iPod touch.

Let’s get started

If you’re not working on a project yet, the first step is of course to create one. To use Popover’s it doesn’t matter what kind of project you start, as long as you don’t forget to set the product on ‘iPad’. For this tutorial, I’ll be sticking to the ‘View application’.

When your new project is loaded, you’ll notice a default view has already been created with the name of your project followed by ‘ViewController.xib’ in the Resources folder. I called the project iPadTutorial, so my main view is called iPadTutorialViewController.xib

The next thing to do is setup a basic interface to attach the Popover to. There are two ways to ‘attach’ a Popover to your interface, the first is by attaching it to a BarButtonItem, the second way to attach it to a pre-defined rectangle. With the last option you can basically attach it to any place on your iPad screen, but for now I’ll use the first one.

Open the .xib of the main ViewController in Interface Builder and drag the following objects from the Library to your view:

  • Navigation Bar
  • Bar Button Item

Your interface should now look like the screenshot below. You can further create your interface of course, but for this tutorial, right now this is all you need.

Now let’s return to Xcode. Since we’re busy with views, let’s just create the second view we’ll be using for the Popover too. Click the File -> New File menu item, and pick the ‘UIViewController subclass’ item. Make sure that at the options panel the options ‘Targeted for iPad’ and ‘With XIB for user interface’ are checked. Click next and give it a fancy name. You can create the interface for the Popover view yourself, but just to check if it’s correctly being loaded, add a UILabel or something.

We’re done with the XIB files for now. Open the header (.h) file for your default View Controller so we can write some code.

In the header file we’ll create the objects for our PopoverController, the UIBarButtonItem and of course the PopoverView itself.

@interface iPadTutorialViewController : UIViewController {
UIPopoverController *popoverController;
IBOutlet UIBarButtonItem *popButton;
MyPopOverView *myPopOver;
}

- (IBAction)showPopover:(id)sender;

@property (nonatomic, retain) UIPopoverController *popoverController;
@property (nonatomic, retain) IBOutlet UIBarButtonItem *popButton;
@property (nonatomic, retain) MyPopOverView *myPopOver;

@end

You might notice the IBAction shown in the code above. This is the action called when you’ll be clicking on the button to show the Popover. More on this later on.

Also synthesize these objects in the main (.m) sourcefile of the view.

@synthesize popoverController, popButton, myPopOver;

To attach these objects to the corresponding objects in the XIB file, we need to do a few things in Interface Builder. Open the .xib file and go to the Document window. You’ll see 3 icons here, File’s Owner, First Responder and View. For now, we only need the first one. Hold the icon while pressing the CTRL-key, and go the the Bar Button Item you’ve created earlier. You’ll see a blue line following your mouse until you release it on the Button. A black popup should show up with in it the name you gave the UIBarButtonItem in the source. Click this name. The Button in the source and the one in the interface are now the same object. The second thing we need to do is attach the button the the IBAction we created. This is done by doing the previous step in reverse. CTRL-click on the BarButtonItem, and drag the blue line to the File’s Owner icon. Then click the name of the IBAction in the black popup, and that’s it. Save the .xib file and close the Interface Builder.

The final part of this tutorial is making the popover actually show up when you click the button. This will be done in the showPopover action we created earlier.

The first thing to do is check whether or not the popover is already visible. If so, we’ll just hide it instead of drawing a new one over it. This can be done with the isPopoverVisible property (The exclamation point on line 1 means ‘not’):

if(![popoverController isPopoverVisible]){
// Popover is not visible
}else{
}

The next thing is to initialize the Popover-view with the XIB file, and attach the view to the controller. Add the following lines:

myPopOver = [[MyPopOverView alloc] initWithNibName:@"MyPopOverView" bundle:nil];
popoverController = [[UIPopoverController alloc] initWithContentViewController:myPopOver];

Make sure the name behind ‘initWithNibName’ exactly matches the filename of the popover view, without the .xib extension of course.

Now let’s actually make the popover show up with the following line of code:

[popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

The sender value of the presentPopoverFromBarButtonItem parameter will cause the popover to show up attached to the button that triggered the showPopover action. With permittedArrowDirections you can specify which directions the popover may be shown. This can be all 4 directions, or Any if you don’t care. For now, let’s leave it on Any.

The last thing to do is make sure the popover disappears when it’s already shown. To do this, add the following code to the ‘else’ block:

[popoverController dismissPopoverAnimated:YES];

When you’ll click on the button with the popover already visible, it will now simply fade out.

That’s it

When you’ll launch your application in the iPad simulator you should now see the interface you created at the beginning. Click on the button in the Navigation Bar to make the Popover appear.

Congratulations on your first Popover-using iPad app ;) .

One more thing…

As previously stated there are two ways to attach the popover to your regular view. We discussed the first way in the tutorial, but I can imagine attaching the popover to the Navigation Bar isn’t always what you want, so here’s the other way.

You can also attach the popover to a rectangular area in your main view. Depending on where it is positioned, it will appear at any side of it. The code for attaching it this way is almost identical to the first, except of the usage of presentPopoverFromRect instead of the FromBarButtonItem, like the example below:

[popoverController presentPopoverFromRect:CGRectMake(10.0f, 10.0f, 10.0f, 10.0f) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

The parameters of CGRectMake are x, y, width and height.

Questions?

If you got any additional questions about this tutorial, leave a reply or contact me by email (See the contact page). Good luck with developing your iPad application.

Updated on April 10, 2010: Fixed an error in the code under the ‘One more thing…’ caption

Source

Click here to download the source.


13 Comments for this entry

  • mars

    im using

    [popoverController presentPopoverFromRect:CGRectMake(10.0f, 10.0f, 10.0f, 10.0f) permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

    but i get an error saying the UIPopoverController may not respond to this…

    according to the docs, its missing the UIView view…I already have an app and i dont wanna use a navbar for it, so im using the cgrect option.

  • Jannis

    @mars thanks for pointing it out, the error has been fixed in the article.

  • MacBuddy

    How about some sample code? I cant get this to work

  • Jannis

    @MadBuddy I’ve added a link to the source.

  • karl

    how can you change the size of the popover, but still init with a nib?

  • Jannis

    You can change the size of the popover with setPopoverContentSize attribute, which uses a CGSize to set the popover’s width and height properties. An example of this is:

    [popoverName setPopoverContentSize:CGSizeMake(250.0f, 100.0f)];

    (Replace popoverName with the name of your UIPopoverController). This example gives the popover a width of 250px and a height of 100px.

  • Nicholas

    Nice work, what if you like more than one button? I would like three or four buttons on the navigation bar.

  • Roland

    Thanks this was very helpfull!

  • Rahul Nagpal

    can we launch popover automatically when application launches if yes than how?

  • Jannis

    @Nicholas: You can have more than one button to use for displaying popover’s, but it’s recommended to use a UIToolbar for that (instead of a standard navigationbar).

    @Rahul Nagpal, yes you can. Only instead of in your UIViewController class, you have to put the code to present your PopoverView in your UIView class.

  • Octavio

    “popoverController = [[[UIPopoverController alloc] initWithContentViewController:myPopOver] retain];”

    When do you get rid of the extra memory reference you are creating with the retain call?

    Thanks.

  • bob

    “popoverController = [[[UIPopoverController alloc] initWithContentViewController:myPopOver] retain];”

    alloc already does a retain, so you don’t need to retain again. you are retaining too much

  • Jannis

    @ above: Tnx for pointing it out, I’ve removed it from the post.

Leave a Reply

Spam protection by WP Captcha-Free

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Blogroll

A few highly recommended websites...

    Archives

    All entries, chronologically...