Laboratory‎ > ‎Objective-C‎ > ‎

HelloPoly

This test application displays a polygon object while letting user increase/decrease the number of sides. Upon user's touch input, the polygon information, the name and its shape is updated respectively.

Aside from actual objective-C code which explains itself, this application had been designed in proper MVC structure

  • Model: PolygonShape
  • View: PolygonView
  • Control: Controller

PolygonShape

//
//  PolygonShape.h
//  HelloPoly
//
//  Created by Hoonio on 2/27/10.
//  Copyright 2010 Hoonio.com. All rights reserved.
//
 
#import <Foundation/Foundation.h>
 
 
@interface PolygonShape : NSObject {
	int numberOfSides;
	int minimumNumberOfSides;
	int maximumNumberOfSides;
	float angleInDegrees;
	float angleInRadians;
	NSString *name;
}
 
@property (setter=setMinimumNumberOfSides) int minimumNumberOfSides;
@property (setter=setMaximukmNumberOfSides) int maximumNumberOfSides;
@property (setter=setNumberOfSides) int numberOfSides;
 
@property (readonly) float angleInDegrees;
@property (readonly) float angleInRadians;
@property (readonly) NSString *name;
 
// method declarations
- (void)setMinimumNumberOfSides:(int)numberOfSidesSet;
- (void)setMaximumNumberOfSides:(int)numberOfSidesSet;
- (void)setNumberOfSides:(int)numberOfSidesSet;
 
- (id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max;
- (id)init;
 
- (float)angleInDegrees;
- (float)angleInRadians;
 
- (NSString *)name;
 
- (void)printOutput;
- (void)dealloc;
 
@end
//
//  PolygonShape.m
//  HelloPoly
//
//  Created by Hoonio on 2/27/10.
//  Copyright 2010 Hoonio.com. All rights reserved.
//
 
#import "PolygonShape.h"
 
 
@implementation PolygonShape
 
@synthesize minimumNumberOfSides, maximumNumberOfSides, numberOfSides;
 
- (void)setMinimumNumberOfSides:(int)numberOfSidesSet {
	if (numberOfSidesSet < 3)
		NSLog(@"Invalid number of sides: %u is less than the minimum of 3 allowed", numberOfSidesSet);
	minimumNumberOfSides = numberOfSidesSet;
	NSLog(@"Setting minimum boundary: %u", numberOfSidesSet);
}
 
- (void)setMaximumNumberOfSides:(int)numberOfSidesSet {
	if (numberOfSidesSet > 12)
		NSLog(@"Invalid number of sides: %u is greater than the maximum of 12 allowed", numberOfSidesSet);
	maximumNumberOfSides = numberOfSidesSet;
	NSLog(@"Setting maximum boundary: %u", numberOfSidesSet);
}
 
- (void)setNumberOfSides:(int)numberOfSidesSet {
	NSLog(@"Setting number of sides as %u over %u", numberOfSidesSet, numberOfSides);
	if (numberOfSidesSet < minimumNumberOfSides)
		NSLog(@"Invalid number of sides: %u is less than the minimum of %u allowed", numberOfSidesSet, 
                    minimumNumberOfSides);
	if (numberOfSidesSet > maximumNumberOfSides)
		NSLog(@"Invalid number of sides: %u is greater than the maximum of %u allowed", numberOfSidesSet, 
                    maximumNumberOfSides);
	numberOfSides = numberOfSidesSet;
}
 
- (id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max{
	// allow superclass to initialize its state first
	if (self = [super init]){
		// do polygon initialization
		if (min < 3)
			NSLog(@"Invalid number of sides: %u is less than the minimum of 3 allowed", min);
		minimumNumberOfSides = min;
		if (max > 12)
			NSLog(@"Invalid number of sides: %u is greater than the maximum of 12 allowed", max);
		maximumNumberOfSides = max;
		if (!(min < sides < max))
			NSLog(@"Invalid number of sides: %u is not within the defined range %u - %u", sides, min, max);
		numberOfSides = sides;
	}
 
	return self;
}
 
// overriding custom initializer with default values
- (id)init{
	// allow superclass to initialize its state first
	if (self = [super init]){
		// do polygon initialization
		numberOfSides = 5;
		minimumNumberOfSides = 3;
		maximumNumberOfSides = 10;
	}
	return self;
}
 
- (float)angleInDegrees{
	return (180 * (numberOfSides - 2) / numberOfSides);
}
 
- (float)angleInRadians{
	return (M_PI * (numberOfSides - 2) / numberOfSides);
}
 
- (NSString *)name{
 
	static NSString *polygonName[] = {nil, @"henagon", @"Digon", @"Triangle", @"Square", @"Pentagon", 
            @"Hexagon", @"Heptagon", @"Octagon", @"Ennegon", @"Decagon", @"Hendecagon", @"Dodecagon", nil};
	return polygonName[numberOfSides];
 
}
 
- (void)printOutput{
	NSLog(@"Hello I am a %d-sided polygon (aka a %@) with angles of %f degrees (%f radians).", numberOfSides, 
            [self name], [self angleInDegrees], [self angleInRadians]);
}
 
- (void)dealloc{
	// Do any cleanup that’s necessary
	NSLog(@"Termination: Polygon shape dealloc");
	[name release];
	// when we’re done, call super to clean us up
	[super dealloc];
}
 
@end


PolygonView

//
//  PolygonView.h
//
//  Created by Hoonio on 3/8/10.
//  Copyright 2010 Hoonio.com. All rights reserved.
//
 
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "PolygonShape.h"
 
@interface PolygonView : UIView {
	IBOutlet PolygonShape *polygon;
}
 
@property (readwrite, assign) PolygonShape *polygon;
 
- (void)setPolygon:(PolygonShape *)polygonInput;
- (NSArray *)pointsForPolygonInRect:(CGRect)rect numberOfSides:(int)numberOfSides;
- (void)drawRect:(CGRect)rect;
 
@end

PolygonView.m

//
//  PolygonView.m
//
//  Created by Hoonio on 3/8/10.
//  Copyright 2010 Hoonio.com. All rights reserved.
//
 
#import "PolygonView.h"
 
@implementation PolygonView
 
- (void)setPolygon:(PolygonShape *)polygonInput {
	polygon = polygonInput;
	[self setNeedsDisplay];
}
 
 
- (NSArray *)pointsForPolygonInRect:(CGRect)rect numberOfSides:(int)numberOfSides { 
	CGPoint center = CGPointMake(rect.size.width / 2.0, rect.size.height / 2.0); 
	float radius = 0.9 * center.x; 
	NSMutableArray *result = [NSMutableArray array];
	float angle = (2.0 * M_PI) / numberOfSides; 
	float exteriorAngle = M_PI - angle; 
	float rotationDelta = angle - (0.5 * exteriorAngle);
 
	for (int currentAngle = 0; currentAngle < numberOfSides; currentAngle++) { 
		float newAngle = (angle * currentAngle) - rotationDelta; 
		float curX = cos(newAngle) * radius; 
		float curY = sin(newAngle) * radius;
		[result addObject:[NSValue valueWithCGPoint:CGPointMake(center.x + curX, center.y + curY)]];
	} 
	return result;
}
 
/*- (void)setNeedsDisplay:(int)numberOfSidesSet {
	coordinates = [self pointsForPolygonInRect:[self bounds] numberOfSides:numberOfSidesSet];
	NSLog(@"Setting coordinates for a %d-sided polygon.", numberOfSidesSet);
}
 
- (void)setPolygonName:(NSString *)currentPolygon {
	polygonName.text = currentPolygon;
}
*/
 
- (void)drawRect:(CGRect)rect { 
	[[UIColor grayColor] set]; 
	UIRectFill ([self bounds]);
 
	NSArray *coordinates = [self pointsForPolygonInRect:[self bounds] numberOfSides:[polygon numberOfSides]];
	NSLog(@"Setting coordinates for a %d-sided polygon.", [polygon numberOfSides]);
 
	CGContextRef context = UIGraphicsGetCurrentContext();
 
	CGContextBeginPath(context);
 
	CGPoint initialPoint = [[coordinates objectAtIndex:0] CGPointValue];
	CGContextMoveToPoint(context, initialPoint.x, initialPoint.y);
	NSLog(@"Initial point at %d, %d", initialPoint.x, initialPoint.y);
 
	for (NSValue *coordinate in coordinates) {
//		if ([coordinate CGPointValue] == nil)
//			break;
//		else {
		CGPoint point = [coordinate CGPointValue];
			CGContextAddLineToPoint(context, point.x, point.y);
//		}
	}
 
	CGContextClosePath(context);
 
	[[UIColor blackColor] setStroke];
	[[UIColor redColor] setFill];
	CGContextDrawPath(context, kCGPathFillStroke);
}
 
@end


Controller

//
//  Controller.h
//
//  Created by Hoonio on 3/6/10.
//  Copyright 2010 Hoonio.com. All rights reserved.
//
 
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "PolygonShape.h"
#import "PolygonView.h"
 
@interface Controller : NSObject {
	IBOutlet PolygonView *polygonView;
    IBOutlet UIButton *decreaseButton;
    IBOutlet UIButton *increaseButton;
    IBOutlet UILabel *numberOfSidesLabel;
 
	IBOutlet UILabel *polygonName;
	IBOutlet PolygonShape *polygon;
}
 
- (IBAction)decrease:(id)sender;
- (IBAction)increase:(id)sender;
- (void)awakeFromNib;
- (void)updateInterface;
 
@end
//
//  Controller.m
//
//  Created by Hoonio on 3/6/10.
//  Copyright 2010 Hoonio.com. All rights reserved.
//
 
#import "Controller.h"
 
 
@implementation Controller
- (IBAction)decrease:(id)sender {
	if ([polygon numberOfSides] > [polygon minimumNumberOfSides])
		[polygon setNumberOfSides:([polygon numberOfSides]-1)];
	[self updateInterface];
	NSLog(@"Polygon dimension decrease: %d", [polygon numberOfSides]);
}
 
- (IBAction)increase:(id)sender {
	if ([polygon numberOfSides] < [polygon maximumNumberOfSides])
		[polygon setNumberOfSides:([polygon numberOfSides]+1)];
	[self updateInterface];
	NSLog(@"Polygon dimension increase: %d", [polygon numberOfSides]);
}
 
- (void)awakeFromNib {
	if ([[NSUserDefaults standardUserDefaults] integerForKey:@"PolygonKind"]) {
		numberOfSidesLabel.text = [NSString stringWithFormat:@"%d", [[NSUserDefaults standardUserDefaults] 
                    integerForKey:@"PolygonKind"]];
	}
	[polygon setMinimumNumberOfSides:3]; 
	[polygon setMaximumNumberOfSides:12];
	[polygon setNumberOfSides:numberOfSidesLabel.text.integerValue];
 
	[polygonView setPolygon:polygon];
	polygonName.text = polygon.name;
	NSLog(@"My polygon: %@", polygon.name);
 
}
 
- (void)updateInterface {
	// set interface state here
	NSLog(@"Entering updateInterface");
	if ([polygon numberOfSides] == [polygon minimumNumberOfSides])
		decreaseButton.enabled = NO;
	else
		decreaseButton.enabled = YES;
 
	if ([polygon numberOfSides] == [polygon maximumNumberOfSides])
		increaseButton.enabled = NO;
	else
		increaseButton.enabled = YES;
 
	numberOfSidesLabel.text = [NSString stringWithFormat:@"%d", [polygon numberOfSides]];
	[polygonView setPolygon:polygon];
	[[NSUserDefaults standardUserDefaults] setInteger:[polygon numberOfSides] forKey:@"PolygonKind"];
 
	polygonName.text = polygon.name;
 
}
 
@end


Comments