views:

490

answers:

1

Hi all, this is my first time posting so please excuse any lapses in stackoverflow etiquette.

I haven't found any example code or any questions that address the problem I'm having, so hopefully someone can shed some light on this.

I'm using Quartz and I have a CATiledLayer on which I have drawn several boxes you can click on. When you click one, I want to redraw that box with a blue outline, but not redraw the rest of the view. From the comments I have read it seems like I should be using setNeedsDisplayInRect instead of setNeedsDisplay once I have clicked inside the bounds of one of the boxes, and set the dirty rect to the size of that box. However, whenever my (void)drawRect:(CGRect)rect function is called, the rect in (void)drawRect:(CGRect)rect is always the size of my view, no matter what rect I tried to invalidate in setNeedsDisplayInRect. I don't think I am calling setNeedsDisplay or setNeedsDisplayInRect anywhere else, but for some reason the entire view is invalidated. If I don't use a CATiledLayer, this problem doesn't appear and DrawRect receives the correct rect when setNeedsDisplayInRect is called.

Here is a simplified version of my code:

#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>

#import "EAGLView.h"
#import "MapViewController.h"


// A class extension to declare private methods
@interface EAGLView ()

@property (nonatomic, retain) EAGLContext *context;

@end

@implementation EAGLView

+(Class)layerClass
{
    return [CATiledLayer class];
}

- (id)initWithFrame:(CGRect)frame
{
    //self.frame.size.width is 920
    //self.frame.size.height is 790
    if (self = [super initWithFrame:frame]) {
        self.backgroundColor = [UIColor whiteColor];

        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        _myContext = CGBitmapContextCreate(NULL, self.frame.size.width, self.frame.size.height, 8, 4*self.frame.size.width, colorSpace, kCGImageAlphaPremultipliedFirst);
        CGColorSpaceRelease(colorSpace);

        _myLayer = CGLayerCreateWithContext(_myContext, self.frame.size, NULL);

        CATiledLayer *animLayer = (CATiledLayer *) self.layer;
        animLayer.levelsOfDetailBias = 2;
        animLayer.tileSize = CGSizeMake(1000,1000);


    }
    return self;    
}


- (void)drawRect:(CGRect)rect {
    // Drawing code, rect is always equal to the size of the view (920,720)

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    testRect = CGRectMake(0, 0, 100.0, 100.0);
    [self setNeedsDisplayInRect:testRect];
}

- (void)dealloc {

    [super dealloc];
}

@end

Has anyone else run into a problem like this? Is this a limitation of CATiledLayer or am I just using it incorrectly? By the way, the reason I am using the CATiledLayer is solely so that I can maintain sharp graphics as I zoom in and out on a UIScrollView. The CATiledLayer is embedded in a UIScrollView, but removing the CATiledLayer from the UIScrollView does not fix this problem. If anyone can suggest a better alternative to get the "vectorized graphics" effect on zoom, please let me know. I've spent a lot of time with CATiledLayer and I just can't get it to do what I want.

Edit: I can remove these lines and still get the same problem:

CATiledLayer *animLayer = (CATiledLayer *) self.layer;
animLayer.levelsOfDetailBias = 2;
animLayer.tileSize = CGSizeMake(1000,1000);
A: 

Well, it seems like if I add the line animLayer.levelsOfDetail = 2; right after animLayer.levelsOfDetailBias, it fixed the problem I had. The correct rect is being sent to drawRect now, and there is no flicker as I update. I guess that was a pretty simple fix, and I need to read up on how to use levelsofDetailBias and levelsOfDetail.

Edit: This actually fixed another problem I had, but I still can't get the correct dirtyRect to be passed to DrawRect, so please disregard this

Rick
please add your edits as a comment or update your question, please do not post comments or updates as answers
Madhup
On second thought, I'm not sure I really understand what's happening. Can anyone clarify this situation?
Rick
Madhup: Huh? This is the questioner's solution to the problem. A solution to the problem *should* be posted as an answer.
Peter Hosey
Rick: You've posted an answer on your own question. As far as I can tell, it answers the question, so there's nothing wrong with that. (Some people screw this up and address other answers or comments in non-answering answers.)
Peter Hosey
Sorry everyone, I posted this answer thinking I had answered my own question, but I was wrong, I still can't figure out how to get the drawRect to get the right dirtyRect.
Rick