Popovers are very common within the iPad user interface but you were restricted to the design provided by Apple. With iOS 5 came a little known class called UIPopoverBackgroundView
which allows you to provide a custom border and arrow for the popover.
The popover
The UIPopoverController
is the class that facilitates the popover view. It takes a custom view controller and then displays it with a neat border and arrow, where the arrow points to its origin. It is ideal for displaying contextual information. The popover user interface is essentially made of three main parts: the border, content, and arrow.
Images
Before we look at the UIPopoverBackgroundView
you will need two images to customize your popover. One image for the border and the other for the arrow.
DISSECTING THE BACKGROUND IMAGE
When designing the background image it is important to note that the image will be stretched. UIImage
allows you to create a stretchable image by defining cap insets. These caps define portions of the image that will not be rescaled whereas the rest of the image is easily tiled when stretched. As seen in the image below the dark area is what will be tiled and the colored corners will not.
Subclassing UIPopoverBackgroundView
The UIPopoverBackgroundView
is an abstract class which has no implementation. We need to subclass it and provide implementations for all its methods and properties. You can read the Apple documentation on all its properties and methods. What is not in the documentation is how to layout the border and arrow using the method layoutSubviews
.
First let’s start by creating an Interface
and subclassing the UIPopoverBackgroundView
.
Make sure to specify your import statement or else the code will not compile. An explanation for each of the instance variables:
-
_borderImageView
: contains the image for the border -
_arrowView
: contains the image for the arrow -
_arrowOffset
: used for the propertyarrowOffset
specified in theInterface
forUIPopoverBackgroundView
. We will see later how this value is used to calculate the position for the arrow. -
_arrowDirection
: used for the propertyarrowDirection
specified in theInterface
forUIPopoverBackgroundView
Let’s fill out the implementation, starting with the designated initializer
Basically we are allocating and initializing the two views and adding them as subviews. Notice how the background image is defined with cap insets. Next, let’s implement all the required methods including the getters and setters for the properties.
The above methods are fairly straightforward with the exception of contentViewInsets
. This method determines the thickness of your border. The higher the number the thicker your border. Finally, the method that lays out our two subviews in their appropriate sizes and location.
The switch statement determines the direction of the arrow and then calculates the location of the arrow and its rotation. Our default arrow image points upwards so we need to change its rotation using an affine transform which takes in radians. The arrowOffset
is calculated and set by theUIPopoverController
which essentially tells us the distance of the arrow from the center of content view. We also have to adjust the height and width of our border view to account for the arrow.
Using the CustomPopoverBackgroundView
Now that we have created the CustomPopoverBackgroundView
we need to set it when creating an instance of the UIPopoverController
Note: the above code will work only in iOS 5
Now run your app and marvel at your newly designed popover.
http://blog.teamtreehouse.com/customizing-the-design-of-uipopovercontroller