Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

chauhan4

macrumors newbie
Original poster
Oct 23, 2009
4
0
hi,
I am trying to complete assignment 3 from the Stanford lectures on iTunes U. They're real interesting but I've run into a problem. I'm trying to update a subview in a window to display the shape of a polygon but setNeedsDisplay is called once and never again. Could someone please help me resolve this bug. Thanks

Code:
//PolygonView header file
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "PolygonShape.h"

@interface PolygonView : UIView/* Specify a superclass (eg: NSObject or NSView) */ {
    IBOutlet PolygonShape *polyShape;
}

@property (retain) PolygonShape *polyShape;

+ (NSArray *)pointsForPolygonInRect:(CGRect)rect numberOfSides:(int)numberOfSides;

@end

//PolygonView implementation file
#import "PolygonView.h"

@implementation PolygonView

@synthesize polyShape;

+ (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;
}
[B]- (void)drawRect:(CGRect)rect[/B]
{
	NSLog(@"Entering drawRect function");
	CGRect bounds = [self bounds];//Here bounds is reference to the subview that was created
	[[UIColor blueColor] set];
	UIRectFill(bounds);//fills the color of the bounds
	NSArray *arraypoints = [PolygonView pointsForPolygonInRect:bounds numberOfSides:polyShape.numberOfSides];//we don't use self here as this is a class method that begins with a '+' (I think)
	//The above statement returns an array with and x and y coordinates of the polygon that is generated using information of numberOfSides	
	CGContextRef context = UIGraphicsGetCurrentContext();//gets the current graphic context which is what we use when you're overriding the drawRect funtion
	CGContextBeginPath(context);//begin drawing the polygon
	CGPoint currentPoint = [[arraypoints objectAtIndex:0] CGPointValue];//retrieve the first coordinate point of the polygon from the array
	CGContextMoveToPoint(context, currentPoint.x, currentPoint.y);//move to the first point of the array
	//Found this code in the documentation to enumerate through an array using NSEnumerator
	NSEnumerator *enumerator = [arraypoints objectEnumerator];
	id object;
	while((object = [enumerator nextObject]))
	{
		currentPoint = [object CGPointValue];
		CGContextAddLineToPoint(context, currentPoint.x, currentPoint.y);
	}
	CGContextClosePath(context);
	[[UIColor redColor] setFill];
	[[UIColor blackColor] setStroke];
	CGContextDrawPath(context, kCGPathFillStroke);
	NSLog(@"drawRect is being called");
	return;
}
	
@end

//Controller header file
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "PolygonShape.h"
#import "PolygonView.h"

@interface Controller : NSObject/* Specify a superclass (eg: NSObject or NSView) */ {
    IBOutlet UIButton *decreaseButton;
    IBOutlet UIButton *increaseButton;
    IBOutlet UILabel *numberOfSidesLabel;
    IBOutlet PolygonShape *polygon;
    IBOutlet PolygonView *polyview;
}

- (IBAction)decrease;
- (IBAction)increase;
- (void)awakeFromNib;
- (void)updateInterface;

@end

//Controller implementation file
#import "Controller.h"
#import "PolygonShape.h"
#import "PolygonView.h"

@implementation Controller

- (IBAction)decrease 
{
    //NSLog(@"I'm in the decrease method");
	polygon.numberOfSides = polygon.numberOfSides - 1;
	[B][self updateInterface];[/B]
	NSLog(@"Polygon: %@", polygon);
	//NSLog(@"The number of sides is %d", polygon.numberOfSides);
}

- (IBAction)increase 
{
	polygon.numberOfSides = polygon.numberOfSides + 1;
	[B][self updateInterface];[/B]
	NSLog(@"Polygon: %@", polygon);
	//NSLog(@"I'm in the increase method");
	//NSLog(@"The number of sides is %d", polygon.numberOfSides);
}

[B]- (void)updateInterface[/B]
{
	NSLog(@"Updating");
	if(polygon.numberOfSides > polygon.minimumNumberOfSides)
	{
		decreaseButton.enabled = YES;
	}
	else
	{
		decreaseButton.enabled = NO;
	}
	
	if(polygon.numberOfSides < polygon.maximumNumberOfSides)
		increaseButton.enabled = YES;
	else
		increaseButton.enabled = NO;
	
	numberOfSidesLabel.text = [NSString stringWithFormat:@"%d", polygon.numberOfSides];
	NSLog(@"The number of sides is %d", polygon.numberOfSides);
	[B][polyview setNeedsDisplay];[/B]
}

- (void)awakeFromNib
{
	//PolygonShape *poly = [PolygonShape alloc]; 
	//[polygon initWithNumberOfSides:numberOfSidesLabel.text.integerValue minimumNumberOfSides:3 maximumNumberOfSides:12];
	[self updateInterface];
	NSLog(@"My polygon = %@", polygon);
	//numberOfSidesLabel.text = [NSString stringWithFormat:@"%@", polygon.numberOfSides];
	//[polygon release];
}
@end

Thanks for your help in advance...
 
Oh, i'm sorry I forgot to update this....I fixed the problem, one of my connections had broken in IB for some reason and thats why it wouldn't display.....Thanks anyway.....
 
I'm working my way though this class as well, but I'm running into a semi-issue. I was having the same issue as the OP where setNeedsDisplay wasn't doing anything. I then linked the PolyView to the controller (or the other way around, still kinda confused about that). This made the call take place, but the polygon was never updating. If I add the line of code

Code:
[polygonView setPolygon:polygon];

then the polygon in the view updates and everything draws correctly. I might be wrong, but shouldn't this line of code never be needed? I have

PolygonView with a polygon instance variable linked to the polygon object in the mainview.xib

Controller with a polygon and polygonView instance variables linked to the polygon object and the view respectively.

and finally

Polygon linked to both the controller and polygonview.

I figure with all these links there should only be the ONE polygon ever in existence, and that pointers are passed around correctly, but like I said, if I don't call that line of code above, the updating draw method is called, but nothing changes (did a
Code:
NSLog(@"%@", polygon)
and it was the same polygon I started with (5 sides, 3 min, 12 max)).
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.