Custom Popover View

The possibility to show popover views (modal or non modal) is a really cool thing within the new iPhone OS 3.2. It allows you to display important information, request some input from the user or present some kind of navigation structure. Anyway, it depends on your application but it helps to focus the user on your main content and to avoid too many context (or better: view layout) changes.

Now I am going to give you just a quick example of how we can display a customized popover view within our application. First of all I want to present a simple popover view when a given toolbar button was pressed. The class UIPopoverController  offers the functionality to show a popover with any given view controller.

We are also able to limit the popover’s view size with the new property contentSizeForViewInPopover  in all UIViewController  classes. If you don’t customize this property, the popover will be shown in its default width of 320px and in full screen height.

After initialization of your UIPopoverController  instance you can call the method presentPopoverFromBarButtonItem: permittedArrowDirections: animated: . The first parameter is used to locate the control which creates the popover view. The second parameter permittedArrowDirections  allows you to restrict the direction of the shown arrow of the popover. To support all orientations and layout changes, UIPopoverArrowDirectionAny  is the best way to go.

-(void) toolbarAction:(id)sender {
   if([self.popoverController isPopoverVisible])
   {
      //close the popover view if toolbar button was touched
      //again and popover is already visible
      //Thanks to @chrisonhismac

      [self.popoverController dismissPopoverAnimated:YES];
      return;
   }

   //build our custom popover view
   UIViewController* popoverContent = [[UIViewController alloc]
                              init];
   UIView* popoverView = [[UIView alloc]
                        initWithFrame:CGRectMake(0, 0, 300, 400)];
   popoverView.backgroundColor = [UIColor blueColor];
   popoverContent.view = popoverView;

   //resize the popover view shown
   //in the current view to the view's size
   popoverContent.contentSizeForViewInPopover =
                              CGSizeMake(300, 400);

   //create a popover controller
   self.popoverController = [[UIPopoverController alloc]
               initWithContentViewController:popoverContent];

   //present the popover view non-modal with a
   //refrence to the toolbar button which was pressed
   [self.popoverController presentPopoverFromBarButtonItem:sender
               permittedArrowDirections:UIPopoverArrowDirectionUp
               animated:YES];

   //release the popover content
   [popoverView release];
   [popoverContent release];
}

In my example application I get the following screen:

post_popover_toolbar-item-popover

So, while showing popover views from toolbar items is very common, it is also often necessary to show popovers when interacting with other UI controls within your screen. Another example will show a popover view triggered from a standard button within my main content view.

I placed a button called popoverButton  which performs the following method when activated. This time we use the method presentPopoverFromRect  and use the button’s frame as source for the direction of the popover’s arrow. The popover implementation is very sophisticated and places the popover so it fits best at the current screen.

-(void) buttonAction:(id)sender {
   //build our custom popover view
   UIViewController* popoverContent = [[UIViewController alloc]
                  init];
   UIView* popoverView = [[UIView alloc]
                  initWithFrame:CGRectMake(0, 0, 200, 300)];
   popoverView.backgroundColor = [UIColor greenColor];
   popoverContent.view = popoverView;

   //resize the popover view shown
   //in the current view to the view's size
   popoverContent.contentSizeForViewInPopover =
                  CGSizeMake(200, 300);

   //create a popover controller
   self.popoverController = [[UIPopoverController alloc]
               initWithContentViewController:popoverContent];

   //present the popover view non-modal with a
   //refrence to the button pressed within the current view
   [self.popoverController presentPopoverFromRect:popoverButton.frame
               inView:self.view
               permittedArrowDirections:UIPopoverArrowDirectionAny
               animated:YES];

   //release the popover content
   [popoverView release];
   [popoverContent release];
}

Using this code will create another popover which will look as shown in the picture below:

post_popover_custom-button-popover

I really like popovers and also the possibility to show them in a modal manner. It is recommended to use modal popover views very rarely because the user’s focus gets lost from the main content. Use them only when it is really necessary and some kind of mandatory input is needed (i.e. accepting terms of use).

You will find the source code of this example at my github repository. The project is called PopoverView.

Leave a Reply

Your email address will not be published. Required fields are marked *