使用CATiledLayer时,setNeedsDisplayInRect重绘整个视图

时间:2010-01-27 05:47:56

标签: iphone core-graphics quartz-graphics tiles

这是我第一次发帖,请原谅stackoverflow礼仪中的任何失误。

我没有找到任何示例代码或任何解决我遇到的问题的问题,所以希望有人可以对此有所了解。

我正在使用Quartz,我有一个CATiledLayer,我已经绘制了几个你可以点击的框。当您单击一个时,我想重绘具有蓝色轮廓的框,但不重绘其余视图。从我看过的评论看来,一旦我在其中一个框的边界内单击,我就应该使用setNeedsDisplayInRect而不是setNeedsDisplay,并将脏矩形设置为该框的大小。但是,每当调用my(void)drawRect:(CGRect)rect函数时,无论我在setNeedsDisplayInRect中尝试使用哪个rect,rect(void)drawRect:(CGRect)rect都是我视图的大小。我不认为我在其他任何地方调用setNeedsDisplay或setNeedsDisplayInRect,但由于某种原因,整个视图无效。如果我不使用CATiledLayer,则在调用setNeedsDisplayInRect时,不会出现此问题,DrawRect会收到正确的rect。

以下是我的代码的简化版本:

#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

有没有其他人遇到这样的问题?这是CATiledLayer的限制还是我只是错误地使用它?顺便说一下,我使用CATiledLayer的原因完全在于我可以在UIScrollView上放大和缩小时保持清晰的图形。 CATiledLayer嵌入在UIScrollView中,但从UIScrollView中删除CATiledLayer并不能解决此问题。如果有人能提出更好的替代方案来获得缩放的“矢量化图形”效果,请告诉我。我花了很多时间在CATiledLayer上,但我无法让它做我想做的事。

编辑:我可以删除这些行并仍然遇到同样的问题:

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

2 个答案:

答案 0 :(得分:1)

好吧,好像我添加了一行animLayer.levelsOfDetail = 2;在animLayer.levelsOfDetailBias之后,它解决了我遇到的问题。正确的rect现在被发送到drawRect,并且我更新时没有闪烁。我想这是一个非常简单的修复,我需要阅读如何使用levelsofDetailBias和levelsOfDetail。

编辑:这实际上解决了我遇到的另一个问题,但我仍然无法将正确的dirtyRect传递给DrawRect,所以请忽略这个

答案 1 :(得分:0)

来自Apple's Q&A:“如果您拨打-setNeedsDisplayInRect:-setNeedsDisplay:,则会重新绘制整个视图。”

似乎-setNeedsDisplayInRect:方法与方法-setNeedsDisplay:没有任何好处。这导致人们猜测这种行为是iOS处理重绘的一个错误。

似乎没有一个干净简单的解决方案。建议之一是将您的视图分解为多个子视图,并仅为受影响的人请求重绘,或者跟踪要自行重绘的区域。

包括我在内的其他一些人也有同样的问题,例如herehere