I'm learning Objective C via the online Stanford iPhone course and am on the 3rd assignment(drawing a polygon in a UIView, adjustable number of sides via user controls). It works just fine except for the redrawing part, I know why it is happening but conceptually am not getting how to fix it.
I've got 3 classes, Controller, PolygonView(the class for the UIView and draw), & PolygonShape(defines & stores the polygon). The controller has an IBOutlet to the PolygonShape class and the PolygonView class has an IBOutlet to PolygonShape as well. Does that mean that if I access PolygonShape from either of those two classes that I'm talking to the same instance with the same data? It appears that they aren't the same instance and I'm confused as to how I would access the same data from both.
With the whole MVC model in my case I suppose the PolygonView being a UIView would access PolygonShape(the model?) through the Controller? but since the controller already initialized the initial instance of the PolygonShape object what is the syntax for PolygonView to talk to access info from my Controller?
I'm new to OO programming and I'm sure it's a simple solution just doesn't seem to be jumping out from reading forums and Google searches. Thanks for any input!
I've got 3 classes, Controller, PolygonView(the class for the UIView and draw), & PolygonShape(defines & stores the polygon). The controller has an IBOutlet to the PolygonShape class and the PolygonView class has an IBOutlet to PolygonShape as well. Does that mean that if I access PolygonShape from either of those two classes that I'm talking to the same instance with the same data? It appears that they aren't the same instance and I'm confused as to how I would access the same data from both.
With the whole MVC model in my case I suppose the PolygonView being a UIView would access PolygonShape(the model?) through the Controller? but since the controller already initialized the initial instance of the PolygonShape object what is the syntax for PolygonView to talk to access info from my Controller?
I'm new to OO programming and I'm sure it's a simple solution just doesn't seem to be jumping out from reading forums and Google searches. Thanks for any input!
Code:
controller.h -->
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "PolygonShape.h"
#import "PolygonView.h"
@interface Controller : NSObject {
IBOutlet UIButton *decreaseButton;
IBOutlet UIButton *increaseButton;
IBOutlet UILabel *numberOfSidesLabel;
IBOutlet UILabel *maxSidesLabel;
IBOutlet UILabel *minSidesLabel;
IBOutlet UILabel *shapeNameLabel;
IBOutlet UILabel *angleRadLabel;
IBOutlet UILabel *angleDegLabel;
IBOutlet PolygonShape *myPoly;
IBOutlet PolygonView *view;
}
- (IBAction)decrease:(id)sender;
- (IBAction)increase:(id)sender;
- (void)updateInterface;
@end
controller.m -->
#import "Controller.h"
@implementation Controller
- (IBAction)decrease:(id)sender {
--myPoly.numberOfSides;
NSLog(@"I’m in the decrease method %i", myPoly.numberOfSides);
[self updateInterface];
}
- (IBAction)increase:(id)sender {
++myPoly.numberOfSides;
NSLog(@"I’m in the increase method");
[self updateInterface];
}
-(void)awakeFromNib {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSInteger savedSides = [prefs integerForKey:@"integerKey"];
NSLog(@"SavedSides: %d",savedSides);
if (savedSides) {
myPoly.numberOfSides = (int)savedSides;
numberOfSidesLabel.text = [NSString stringWithFormat:@"%d", (int)savedSides];
} else {
myPoly.numberOfSides = numberOfSidesLabel.text.integerValue;
}
myPoly = [[PolygonShape alloc] initWithNumberOfSides:numberOfSidesLabel.text.integerValue minimumNumberOfSides:3 maximumNumberOfSides:12];
NSLog (@"My polygon: %@", myPoly);
numberOfSidesLabel.text = [NSString stringWithFormat:@"%i", myPoly.numberOfSides];
[self updateInterface];
}
-(void)updateInterface {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setInteger:myPoly.numberOfSides forKey:@"integerKey"];
if(myPoly.numberOfSides == myPoly.minimumNumberOfSides) {
decreaseButton.enabled = NO;
} else {
decreaseButton.enabled = YES;
}
if(myPoly.numberOfSides == myPoly.maximumNumberOfSides) {
increaseButton.enabled = NO;
} else {
increaseButton.enabled = YES;
}
numberOfSidesLabel.text = [NSString stringWithFormat:@"%i", myPoly.numberOfSides];
shapeNameLabel.text = [myPoly name];
angleDegLabel.text = [NSString stringWithFormat:@"%f", [myPoly angleInDegrees]];
angleRadLabel.text = [NSString stringWithFormat:@"%f", [myPoly angleInRadians]];
maxSidesLabel.text = [NSString stringWithFormat:@"%i", myPoly.maximumNumberOfSides];
minSidesLabel.text = [NSString stringWithFormat:@"%i", myPoly.minimumNumberOfSides];
[view setNeedsDisplay];
}
@end
PolygonView.h -->
#import "PolygonShape.h"
@interface PolygonView : UIView {
IBOutlet PolygonShape *myPoly;
}
-(void)drawRect:(CGRect)rect;
@end
PolygonView.m -->
#import "PolygonView.h"
@implementation PolygonView
+ (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)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect bounds = [self bounds];
[[UIColor darkGrayColor] set];
UIRectFill (bounds);
[[UIColor lightGrayColor] setFill];
[[UIColor blueColor] setStroke];
CGContextDrawPath (context, kCGPathFillStroke);
NSArray *pts;
int i;
NSValue *theValue;
CGPoint thePoint;
pts = [PolygonView pointsForPolygonInRect:bounds numberOfSides:myPoly.numberOfSides];
CGContextBeginPath (context);
theValue = [pts objectAtIndex:(NSInteger)0];
thePoint = [theValue CGPointValue];
CGContextMoveToPoint (context, thePoint.x, thePoint.y);
for (i = 1; i < myPoly.numberOfSides; i++) {
theValue = [pts objectAtIndex:(NSInteger)i];
thePoint = [theValue CGPointValue];
CGContextAddLineToPoint (context, thePoint.x, thePoint.y);
}
theValue = [pts objectAtIndex:(NSInteger)0];
thePoint = [theValue CGPointValue];
CGContextAddLineToPoint(context, thePoint.x, thePoint.y);
CGContextDrawPath (context, kCGPathFillStroke);
return;
}
@end
PolygonShape.h -->
#import <Foundation/Foundation.h>
@interface PolygonShape : NSObject {
int numberOfSides;
int minimumNumberOfSides;
int maximumNumberOfSides;
}
@property int numberOfSides;
@property int minimumNumberOfSides;
@property int maximumNumberOfSides;
@property (readonly) float angleInDegrees;
@property (readonly) float angleInRadians;
@property (readonly) NSString *name;
@property (readonly) NSString *description;
- (id) init;
- (id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max;
- (void) dealloc;
@end
PolygonShape.m -->
#import "PolygonShape.h"
@implementation PolygonShape
@synthesize numberOfSides, minimumNumberOfSides, maximumNumberOfSides;
- (void) setNumberOfSides:(int) numSides {
if(numSides < minimumNumberOfSides) {
NSLog(@"Invalid number of sides: %d is less than the minimum of %d allowed.", numSides, minimumNumberOfSides);
} else if(numSides > maximumNumberOfSides) {
NSLog(@"Invalid number of sides: %d is greater than the maximum of %d allowed.", numSides, maximumNumberOfSides);
} else {
numberOfSides = numSides;
}
}
- (void) setMinimumNumberOfSides:(int) minSides {
if(minSides > 2) {
minimumNumberOfSides = minSides;
} else {
NSLog(@"Invalid number of sides: %d is less than the minimum of 3 allowed.", minSides);
}
}
- (void) setMaximumNumberOfSides:(int) maxSides {
if(maxSides <= 12) {
maximumNumberOfSides = maxSides;
} else {
NSLog(@"Invalid number of sides: %d is greater than the maximum of 12 allowed.", maxSides);
}
}
- (id)initWithNumberOfSides:(int)sides minimumNumberOfSides:(int)min maximumNumberOfSides:(int)max {
if (self = [super init]) {
[self setMinimumNumberOfSides:min];
[self setMaximumNumberOfSides:max];
[self setNumberOfSides:sides];
}
return self;
}
- (id)init {
return [self initWithNumberOfSides: 5 minimumNumberOfSides: 3 maximumNumberOfSides: 10 ];
}
- (float) angleInDegrees {
return (180 * (numberOfSides - 2) / numberOfSides);
}
- (float) angleInRadians {
return (M_PI * (numberOfSides - 2) / numberOfSides);
}
- (NSString *) name {
NSDictionary *names = [NSDictionary dictionaryWithObjectsAndKeys: @"Triangle", [NSNumber numberWithInt:3], @"Square", [NSNumber numberWithInt:4],
@"Pentagon", [NSNumber numberWithInt:5],
@"Hexagon", [NSNumber numberWithInt:6],
@"Heptagon", [NSNumber numberWithInt:7],
@"Octagon", [NSNumber numberWithInt:8],
@"Nonagon", [NSNumber numberWithInt:9],
@"Decagon", [NSNumber numberWithInt:10],
@"Hendecagon", [NSNumber numberWithInt:11],
@"Dodecagon", [NSNumber numberWithInt:12], nil];
return [names objectForKey:[NSNumber numberWithInt:[self numberOfSides]]];
}
- (NSString *) description {
return [NSString stringWithFormat:@"Hello I am a %d-sided %@ with angled of %f degrees (%f radians).", [self numberOfSides], [self name], [self angleInDegrees], [self angleInRadians]];
}
- (void) dealloc {
NSLog(@"Deallocating...");
[super dealloc];
}
@end