In this post, we will learn how to create an iPhone application that creates the graphic shown below, using the UIKit framework.
Quoting from the Apple Developer website:
The UIKit framework provides the classes needed to construct and manage an application’s user interface for iOS. It provides an application object, event handling, drawing model, windows, views, and controls specifically designed for a touch screen interface.
It is assumed that you have some degree of familiarity with the Xcode IDE. In particular, you should know how to create and run projects, add files to existing projects and use the Attribute Inspector and the Identity Inspector (located in the right hand-side panel).
Now simply follow these steps.
STEP 1
Open a new project in Xcode (iOS application – Single View Application).In the Deployment Info, select iPhone in the Devices menu and portrait in the Device Orientation.
STEP 2
Create a new file (Cocoa Touch — Objective-C class) called drawShapes. Xcode will create the header and implementation files automatically:
- drawShapes.h
- drawShapes.m
Copy the contents below in these files:
#import <UIKit/UIKit.h> @interface drawShapes : UIView @end
All we have done above is to declare our own little class called “drawShapes” and specified that this class inherits from the UIView class. All of the graphics commands used in this example are part of the drawRect method. The drawRect method is defined in the UIView class and overridden here by our custom graphics commands, as detailed below in the implementation file for our class.
#import "drawShapes.h" @implementation drawShapes - (void)drawRect:(CGRect)rect { CGRect quad; UIBezierPath *path; UIColor* fillColor; UIColor* strokeColor; // rectangular tiling of the iPhone screen for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { float x = 64*i; float y = 96*j; float width = 64; float height = 96; quad = CGRectMake(x, y, width, height); path = [UIBezierPath bezierPathWithRect:quad]; float R = (arc4random() % 255)/255.; float G = (arc4random() % 255)/255.; float B = (arc4random() % 255)/255.; fillColor = [UIColor colorWithRed:R green:G blue:B alpha:1.0]; [fillColor setFill]; [path fill]; strokeColor = [UIColor colorWithRed:R green:G blue:B alpha:1.0]; [strokeColor setStroke]; [path stroke]; } } // draw a red circle with a black perimeter quad = CGRectMake(100, 100, 120, 120); path = [UIBezierPath bezierPathWithOvalInRect:quad]; fillColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0]; [fillColor setFill]; [path fill]; strokeColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0]; [strokeColor setStroke]; [path stroke]; // custom drawing: a white arrow with a black outline { UIBezierPath* arrowPath = [UIBezierPath bezierPath]; // define the path [arrowPath moveToPoint:CGPointMake(0.0, 0.0)]; [arrowPath addLineToPoint:CGPointMake(30.0, 0.0)]; [arrowPath addLineToPoint:CGPointMake(30.0, -5.0)]; [arrowPath addLineToPoint:CGPointMake(40.0, 5.0)]; [arrowPath addLineToPoint:CGPointMake(30.0, 15.0)]; [arrowPath addLineToPoint:CGPointMake(30.0, 10.0)]; [arrowPath addLineToPoint:CGPointMake(0.0, 10.0)]; [arrowPath closePath]; // coordinate transformation using the current context { CGContextRef context = UIGraphicsGetCurrentContext (); float PI = 3.1415; CGContextTranslateCTM(context, 170, 125); CGContextScaleCTM(context, 2, 2); CGContextRotateCTM(context, PI/2.0); } // set the fill color to white fillColor = [UIColor whiteColor]; [fillColor setFill]; [arrowPath fill]; // set the outline to black strokeColor = [UIColor blackColor]; [strokeColor setStroke]; [arrowPath stroke]; } } @end
Most of the code is self-explanatory and you can see that we specify a random color for filling and stroking (drawing the border on) each rectangle .
For drawing the circle, we specify the bounding box inside which it is inscribed.
Finally, we define a custom shape (the arrow) using the following coordinates for the individual points (the seven points are traversed in clock-wise order starting from the origin).
To move the arrow to the location shown in the iPhone screenshot above, coordinate transformations are applied, in the following order:
- rotate clockwise by 90 degrees (π/2 radians) about the origin
- scale by a factor of 2 along X and Y
- translate by 170px along X and 125px along Y
Note that these transformations need to be listed in reverse order in the code:
CGContextTranslateCTM(context, 170, 125); CGContextScaleCTM(context, 2, 2); CGContextRotateCTM(context, PI/2.0);
As an aside, the “CG” stands for Core Graphics and “CTM” stands for current transformation matrix. Unlike C++, Objective-C does not have namespaces. Thus, one needs to be careful to avoid name collisions between different functions. Hence the ubiquitous prefixes all over the place like CG, NS (NextStep legacy) and UI (user interface).
STEP 3
Click on “Main_iPhone.storyboard”. If you wish, you can change the background color by using the appropriate selections in the Attribute Inspector panel. But more importantly, open the Identity Inspector and select the class you just created (drawShapes) in the very first drop-down menu.
STEP 4
That’s it! Build and run your application and you should see the iPhone screen fill up with the graphic shown in the screenshot above.
—
As you can see, it does not take much to create and display simple graphics for iOS. In later posts, we will explore other graphics frameworks in detail, including Core Graphics and OpenGL-ES. In my next post, I will show you how to add images to your view.