2
votes

I'm trying to follow a guide on how to draw some shapes on screen but at the app launch it works fine but I can't "re-draw" the shapes using setNeedsDisplay I've tried a lot of stuff floating around like executing on main thread but it doesn't work.

My App is Made of this:

enter image description here

My UIView has it's own class, DrawView. Here is my code:

DrawView.h

#import <UIKit/UIKit.h>

NSInteger drawType;

@interface DrawView : UIView

-(void)drawRect:(CGRect)rect;
-(void)drawNow:(NSInteger)type;

@end

DrawView.m

#import "DrawView.h"

@implementation DrawView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();
    UIColor *color = [UIColor orangeColor];
    CGContextSetStrokeColorWithColor(context, color.CGColor);
    CGContextSetFillColorWithColor(context, color.CGColor);

    NSLog(@"Type: %i",drawType);

    switch (drawType) {
            case 0:
                CGContextMoveToPoint(context, 10, 100);
                CGContextAddLineToPoint(context, 300, 300);
                CGContextSetLineWidth(context, 2.0);
                CGContextStrokePath(context);
                break;
            case 1:
                CGContextAddEllipseInRect(context,CGRectMake(10, 100, 300,440));
                CGContextDrawPath(context, kCGPathFillStroke);
                break;
            case 2:
                CGContextAddRect(context, CGRectMake(10, 100,300,300));
                CGContextDrawPath(context, kCGPathFillStroke);
                break;
            default:
                break;
    }

}


-(void)drawNow:(NSInteger)type {
    drawType = type;
    NSLog(@"Draw Now! %i",drawType);

    //[self setNeedsDisplay]; // Not working...
    //[self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES]; // Not Working
}

@end

ViewController.h

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

DrawView *mydraw;

@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UISegmentedControl *drawTypeSW;

- (IBAction)drawNow:(id)sender;
@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize drawTypeSW;

- (void)viewDidLoad
{
    [super viewDidLoad];
    mydraw = [[DrawView alloc] init];
}

- (void)viewDidUnload
{
    [self setDrawTypeSW:nil];
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (IBAction)drawNow:(id)sender {
    [mydraw drawNow:drawTypeSW.selectedSegmentIndex];
}
@end

When I open the app a line is draw but when I try to draw something else using the button Draw Now it doesn't work, nothing happens and - (void)drawRect:(CGRect)rect is not called. Why? What am I missing?

Thank you ;)

1

1 Answers

3
votes

Further Edit, final resolution: The DrawView being created in viewDidLoad wasn't being added as a subview to the ViewController. Adding the following line should make it appear correctly (in addition to other fixes below):

[self.view addSubview:mydraw];

Edit: An extension to my answer (which still stands, but I think isn't the core of the problem anymore). You're declaring myDraw outside of the interface (and doing something similar in DrawView's header file). Instead of

DrawView *mydraw;

@interface ViewController : UIViewController
//snip
@end

try:

@interface ViewController : UIViewController
{
DrawView *mydraw;
}
//snip
@end

Original answer: The variable myDraw hasn't been properly initialised - UIViews need to be initialised using either initWithFrame (for programmatic creation) or initWithCoder (when in a nib or storyboard). Using init to create it means it has a frame location/size of 0 (and other UIView functionality may be not initalised properly), which in turn means it won't draw properly.

Try either a) creating a UIView in your nib/storyboard, turning it into a DrawView, and making the drawView field in your ViewController definition an outlet for that view. Or b) Remove it from your nib, create your DrawView using initWithFrame, specifying a location and size on the screen for it.