16
votes

I am a beginner in iOS programming, so sorry if my question is a stupid question.

I am trying to make an app which performs custom drawing on a loaded image.

To do it, I found out that a solution is to subclass UIView and edit the drawRect method.

I made that on the following code which activates on an IBAction linked to a button in the Interface Builder storyboard file.

UIImageView *image = [[UIImageView alloc] initWithImage: [UIImage imageNamed:     @"SampleImage.jpg"]]; 
image.frame = previewView.frame;
[image setContentMode:UIViewContentModeScaleAspectFit];       

[previewView addSubview:image];

customView *aCustomView = [[customView alloc] initWithFrame: CGRectMake(image.bounds.origin.x, image.bounds.origin.y, image.bounds.size.width, image.bounds.size.height)];
[previewView addSubview:aCustomView];

customView is the UIView subclass that I created, whose init and drawRect methods are set like this:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    NSLog(@"INITIALIZING");
    if (self) {
        // Initialization code
        [self setBackgroundColor:[UIColor clearColor]];
    }
    return self;
}


- (void)drawRect:(CGRect)rect
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    NSLog(@"DRAWING");

    CGContextClearRect(ctx, rect);

    CGContextSetRGBFillColor(ctx, 0, 255, 0, 0.3);
    CGContextFillEllipseInRect(ctx, rect); 

    CGContextSetRGBStrokeColor(ctx, 255, 0, 0, 1);
    CGContextSetLineWidth(ctx, 2);
    CGContextStrokeEllipseInRect(ctx, rect);
}

The problem that I have is that no drawing is made and on NSLog I have the "INITIALIZING" message, but not the "DRAWING" drawing.

So basically it makes the initWithFrame, but it doesn't call the drawRect method.

Could you please point me what am I doing wrong?

4

4 Answers

19
votes
  1. Make sure your new view class is subclassing the UIView, not the UIImageView.
  2. To make sure the new view is showing up, you will need to do [viewContainer addSubView:] to get the drawRect to be called.

Ref from the doc:

The UIImageView class is optimized to draw its images to the display. UIImageView will not call drawRect: a subclass. If your subclass needs custom drawing code, it is recommended you use UIView as the base class.

https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIImageView_Class/Reference/Reference.html

10
votes

Paolo,

Here are a few things you can try:

  1. in initWithFrame, check that the frame variable contains what you would expect it to: NSLog(@"Frame: %@", NSStringFromCGRect(frame));
  2. Try calling [preview setNeedsDisplay]; after adding it to its superview

Lastly, I would change

image.frame = previewView.frame;

with:

image.bounds = CGRectMake(0, 0, previewView.frame.size.width, previewView.frame.size.height);

3
votes

May be the question is aCustomView's frame is (0,0,0,0).
You can try to pass a constant CGRect param, like this : CGRectMake(5, 5, 100, 100)。

0
votes

The answer in my case was different from all the answers I've read for similar questions, and perhaps will help someone else. It turned out that on my Storyboard, "Inherit Module From Target" was unchecked, while at the same time the Module was None. I added the checkmark and the draw method was called the next time I ran the app.