Advertisement
iOS SDK

Create Eye-Catching Navigation with AwesomeMenu

by

This tutorial will teach you how to create an eye-catching iOS menu using the AwesomeMenu open-source project. Read on!


Project Preview

The following is a short demo of AwesomeMenu in action:

Note that all the icons provided by AwesomeMenu are completely customizable. The default star/plus icons above are used solely for demonstration purposes.


Step 1: Create a New Xcode Project

Open Xcode and create a new iOS project. Select "Single View Application" and then click "Next".

Figure 1: Project Template Selection

Name the application AwesomeMenuDemo and enter appropriate values for the remaining text input fields. Select "iPhone" from the devices drop-down and make sure "Use Automatic Reference Counting" is selected. Do not select "Use Storyboards" or "Include Unit Tests".

Figure 2: New Project Creation

Step 2: Add Project Resources

The next step is to download the AwesomeMenu code from the official project GitHub page. After you have access to the files, you'll need to drag two folders into your own project: the "AwesomeMenu" folder containing the AwesomeMenu and AwesomeMenuItem classes, and the "Images" folder containing the star and plus sign images.

When you drag the image into Xcode, be sure to check the "Copy items into destination group's folder" checkbox, select the "Create groups for any added folders" radio button, and check the box next to "AwesomeMenuDemo" in the Add to targets table.

Figure 3: New Project Creation

Step 3: Add the QuartzCore Framework

The animation's provided by AwesomeMenu are dependent on the QuartzCore framework. To add this framework, select the AwesomeMenuDemo project in the Project Navigator pane, and then click the "Build Phases" tab. Next expand the "Link Binary with Libraries" drop-down and click the "plus" icon to add a new framework.

Figure 4: Build Phases - Adding a Library

Select QuartzCore from the list to add the framework to your project.

Figure 5: Select QuartzCore

If you've completed the above successfully, you should now see the "QuartzCore" framework in the Project Navigator to the left. You can either leave it where it is or drag it into the "Frameworks" folder to keep things organized.


Step 4: Import AwesomeMenu Headers

Now jump on over to the ViewController.h file. You'll need to import the AwesomeMenu classes into the ViewController with the following code:

#import <UIKit/UIKit.h>
#import "AwesomeMenu.h"

This will allow the project's main view controller to use the AwesomeMenu functionality.


Step 5: Disable ARC for AwesomeMenu

If you followed the instructions from step 1, the project you created is using Automatic Reference Counting (ARC) for memory management. ARC is a phenomenal method of managing application memory, but AwesomeMenu was written with Manual Reference Counting (MRC), and consequently cannot be compiled inside of an ARC project without some modification.

While you could try to convert the AwesomeMenu project from MRC to ARC manually, I wouldn't recommend doing so. Instead, you can simply set the -fno-objc-arc compiler flag on each of the AwesomeMenu source code files to tell the compiler not to apply ARC on those files. Cool, huh?

Fortunately, doing this is easy. Go to the "Build Phases" tab for your project and expand the "Compile Sources" drop-down. Double-click the AwesomeMenu.m file and a popup box with a textfield will appear. Enter "-fno-objc-arc" in this box to apply the compiler flag and then click "Done".

Figure 6: Adding Compiler Flags

Next, do the same thing for the AwesomeMenuItem.m file.

With these flags in place, the compiler knows to apply ARC to all source code files in your project except for the two non-arc files related to AwesomeMenu.


Step 6: Create the Menu

First, let's create an instance of AwesomeMenu and place it in the center of the view controller:

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    
    AwesomeMenu *menu = [[AwesomeMenu alloc] initWithFrame:self.view.frame
                                                     menus:nil];
    
    [self.view addSubview:menu];
    
}

For now, the menus parameter was set to nil, but in the next step we will replace this with an array of AwesomeMenuItem objects. Go ahead and run the project and you should see a plus sign in the center of the screen. Toggling the icon will work, but no menu options are displayed yet.

Figure 8: Adding the AwesomeMenu Object

Step 7: Add Menu Items

Each menu item provided by AwesomeMenu can have three different images associated with it: a background image, a highlighted background image, and a content image. By default, AwesomeMenu includes the following images for these roles:

Figure 9: AwesomeMenu Default Images

Go ahead and create a UIImage object to refer to each of these files:

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    
    UIImage *storyMenuItemImage = [UIImage imageNamed:@"bg-menuitem.png"];
    UIImage *storyMenuItemImagePressed = [UIImage imageNamed:@"bg-menuitem-highlighted.png"];
    UIImage *starImage = [UIImage imageNamed:@"icon-star.png"];

    AwesomeMenu *menu = [[AwesomeMenu alloc] initWithFrame:self.view.frame
                                                     menus:nil];

Now create your first two menu options, place them in an NSArray, and assign that array to the menu object's menus parameter:

    UIImage *storyMenuItemImage = [UIImage imageNamed:@"bg-menuitem.png"];
    UIImage *storyMenuItemImagePressed = [UIImage imageNamed:@"bg-menuitem-highlighted.png"];
    UIImage *starImage = [UIImage imageNamed:@"icon-star.png"];
    
    
    AwesomeMenuItem *starMenuItem1 = [[AwesomeMenuItem alloc] initWithImage:storyMenuItemImage
                                                           highlightedImage:storyMenuItemImagePressed
                                                               ContentImage:starImage
                                                    highlightedContentImage:nil];
    AwesomeMenuItem *starMenuItem2 = [[AwesomeMenuItem alloc] initWithImage:storyMenuItemImage
                                                           highlightedImage:storyMenuItemImagePressed
                                                               ContentImage:starImage
                                                    highlightedContentImage:nil];

    
    NSArray *menuOptions = [NSArray arrayWithObjects:starMenuItem1, starMenuItem2, nil];
    
    AwesomeMenu *menu = [[AwesomeMenu alloc] initWithFrame:self.view.frame
                                                     menus:menuOptions];
    
    [self.view addSubview:menu];

Build and run the project now, and should see a screen similar to the following:

Figure 10: Adding First Menu Options

As you add additional menu items, AwesomeMenu will automatically place them within a predefined angle. By default, the angle is equal to a full circle, with the center being the "plus" sign.

Add three more menu items to see this effect in action:

    
    AwesomeMenuItem *starMenuItem1 = [[AwesomeMenuItem alloc] initWithImage:storyMenuItemImage
                                                           highlightedImage:storyMenuItemImagePressed
                                                               ContentImage:starImage
                                                    highlightedContentImage:nil];
    AwesomeMenuItem *starMenuItem2 = [[AwesomeMenuItem alloc] initWithImage:storyMenuItemImage
                                                           highlightedImage:storyMenuItemImagePressed
                                                               ContentImage:starImage
                                                    highlightedContentImage:nil];
    
    AwesomeMenuItem *starMenuItem3 = [[AwesomeMenuItem alloc] initWithImage:storyMenuItemImage
                                                           highlightedImage:storyMenuItemImagePressed
                                                               ContentImage:starImage
                                                    highlightedContentImage:nil];
    
    AwesomeMenuItem *starMenuItem4 = [[AwesomeMenuItem alloc] initWithImage:storyMenuItemImage
                                                           highlightedImage:storyMenuItemImagePressed
                                                               ContentImage:starImage
                                                    highlightedContentImage:nil];
    
    AwesomeMenuItem *starMenuItem5 = [[AwesomeMenuItem alloc] initWithImage:storyMenuItemImage
                                                           highlightedImage:storyMenuItemImagePressed
                                                               ContentImage:starImage
                                                    highlightedContentImage:nil];
    
    NSArray *menuOptions = [NSArray arrayWithObjects:starMenuItem1, starMenuItem2, starMenuItem3, starMenuItem4, starMenuItem5, nil];
    
    AwesomeMenu *menu = [[AwesomeMenu alloc] initWithFrame:self.view.frame
                                                     menus:menuOptions];
    
    [self.view addSubview:menu];

Your menu should now look like the following:

Figure 11: Adding Additional Menu Items

Step 8: Customize Explosion Angles

The current effect will cause menu options to explode out in a 360 degree circle around the menu button. This works great when the menu is in the center of the screen, but you're likely to want to reposition the menu start point to the top, bottom, or corner of the device.

Two menu properties work together to allow you to control this: menuWholeAngle and rotateAngle. The mathematical principles involved are beyond the scope of this tutorial, but the following screenshots illustrate the most useful combinations:

Upper Right Quad

menuWholeAngle: M_PI / 180 * 90
rotateAngle: M_PI / 180 * -90

Upper Left Quad

menuWholeAngle: M_PI / 180 * -90
rotateAngle: M_PI / 180 * 90

Lower Left Quad

menuWholeAngle: M_PI / 180 * -90
rotateAngle: M_PI / 180 * -90

Lower Right Quad

menuWholeAngle: M_PI / 180 * 90
rotateAngle: M_PI / 180 * 90

Right Semi

menuWholeAngle: M_PI / 180 * 180

Left Semi

menuWholeAngle: M_PI / 180 * -180

As an example, to implement the lower-right quadrant values specified above, modify the project code like so:

    AwesomeMenu *menu = [[AwesomeMenu alloc] initWithFrame:self.view.frame
                
                                                     menus:menuOptions];
    
    // Lower-right Quadrant
    menu.menuWholeAngle = M_PI / 180 * 90;
    menu.rotateAngle = M_PI / 180 * 90;

    [self.view addSubview:menu];

In addition to controlling the menu option placement angles, you can also control the menu options' distance from center with the endRadius property. Play around with this value to see how it works.


Step 9: Customize Menu Placement

Now that you know how to control the angle and distance of the menu option placement, you are far more likely to want to place the menu in one of the four corners of the screen. In order to do so, you need to customize the starting point for the menu button. You can do this with the startPoint property, like so:

    // Lower-right Quadrant
    menu.menuWholeAngle = M_PI / 180 * 90;
    menu.rotateAngle = M_PI / 180 * 90;
    
    menu.startPoint = CGPointMake(30.0f, 30.0f);

    [self.view addSubview:menu];

The line added above will place the menu at point (30, 30) on the iPhone screen. In other words, it will now appear in the top left corner, and should look like this:

Figure 13: Repositioning the Menu

As you can see, repositioning the menu start point is easy. Just be sure to only display as many menu options as you can reasonably fit within the angle constraint set.


Step 9: Respond to Menu Selection

Now that you know how to create a customized menu, you're ready to implement each option. Whenever a user taps on one of the menu option butons, a message is sent to the AwesomeMenu delegate with the index number of the option selected. In order to access that index value, you'll need to implement the AwesomeMenuDelegate.

First, open ViewController.h and specify that it will conform to the delegate protocol:

#import <UIKit/UIKit.h>
#import "AwesomeMenu.h"

@interface ViewController : UIViewController <AwesomeMenuDelegate>

Next, switch to ViewController.m and add the delegate implementation:

- (void)AwesomeMenu:(AwesomeMenu *)menu didSelectIndex:(NSInteger)idx
{
    NSLog(@"Select the index : %d",idx);
}

You'll also need to specify that the view controller is the delegate for the menu, like so:

    NSArray *menuOptions = [NSArray arrayWithObjects:starMenuItem1, starMenuItem2, starMenuItem3, nil];
    
    AwesomeMenu *menu = [[AwesomeMenu alloc] initWithFrame:self.view.frame
                                                     menus:menuOptions];    

    menu.delegate = self;

At this point you can figure out which menu option was selected by mapping the index clicked to the menuOptions array. To complete the menu navigation, you could add a new view controller to the screen or simply modify the existing view controller as necessary. Because the exact implementation will be specific to your own applications, doing so will be left as an exercise for the reader.


Conclusion

AwesomeMenu is an eye-catching and exciting open-source project for customizing your app's navigation controls. I hope you've enjoyed this tutorial, and feel free to leave comments or questions below. You can also reach me via Twitter by sending a message to @markhammonds.

Related Posts