2010-01-27 5 views
1

это мой первый пост, поэтому, пожалуйста, извините любые упущения в методе stackoverflow.setNeedsDisplayInRect перерисовывает весь вид при использовании CATiledLayer

Я не нашел ни одного примерного кода или вопросов, которые касаются проблемы, с которой я столкнулся, поэтому, надеюсь, кто-то может пролить свет на это.

Я использую Quartz, и у меня есть CATiledLayer, на котором я нарисовал несколько полей, на которые вы можете щелкнуть. Когда вы нажмете один, я хочу перерисовать этот ящик с синим контуром, но не перерисовывать остальную часть представления. Из комментариев, которые я прочитал, похоже, что я должен использовать setNeedsDisplayInRect вместо setNeedsDisplay, как только я щелкнул внутри границ одного из полей, и установите для параметра dirty rect значение этого поля. Однако, когда вызывается моя (void) функция drawRect: (CGRect) rect, прямая в (void) drawRect: (CGRect) rect всегда является размером моего представления, независимо от того, какой прямоугольник я пытался сделать недействительным в setNeedsDisplayInRect. Я не думаю, что я вызываю setNeedsDisplay или setNeedsDisplayInRect где-нибудь еще, но по какой-то причине весь вид недействителен. Если я не использую CATiledLayer, эта проблема не появляется, и DrawRect получает правильный прямоугольник при вызове setNeedsDisplayInRect.

Вот упрощенная версия моего кода:

#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, но удаление CATiledLayer из UIScrollView не устраняет эту проблему. Если кто-то может предложить лучшую альтернативу для получения эффекта «векторной графики» при масштабировании, пожалуйста, дайте мне знать. Я потратил много времени на CATiledLayer, и я просто не могу заставить его делать то, что я хочу.

Edit: я могу удалить эти строки и до сих пор получить ту же проблему:

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

ответ

1

Ну, это, кажется, что если я добавить строку animLayer.levelsOfDetail = 2; сразу после animLayer.levelsOfDetailBias, он исправил проблему, которая у меня была. Правильный прямоугольник отправляется теперь в drawRect, и при обновлении нет мерцания. Я думаю, это было довольно простое исправление, и мне нужно прочитать, как использовать levelsofDetailBias и levelsOfDetail.

Edit: Это на самом деле фиксируется еще одна проблема у меня была, но я до сих пор не могу получить правильный dirtyRect быть передан DrawRect, поэтому не обращайте внимания на этот

+0

, пожалуйста, добавьте свои изменения как комментарий или обновите свой вопрос, пожалуйста, не публикуйте комментарии или обновления в качестве ответов. –

+0

С другой стороны, я не уверен, что я действительно понимаю, что происходит. Может ли кто-нибудь прояснить эту ситуацию? – Rick

+1

Мадхуп: А? Это решение этого вопроса. Решение проблемы * должно быть опубликовано как ответ. –

0

От Apple's Q&A: «весь вид будет перерисовывать если вы звоните -setNeedsDisplayInRect: или -setNeedsDisplay:. "

Похоже, что метод -setNeedsDisplayInRect: не дает никаких преимуществ по методу -setNeedsDisplay:. Это привело к предположениям, что это поведение является ошибкой в ​​обработке iOS перерисовки.

Не похоже, чтобы было чистое и простое решение. Среди предложений - разбить свой взгляд на несколько подзонов и запросить перерисовку только для тех, которые затронуты, или отслеживать область, которую нужно перерисовать самостоятельно.

Некоторые другие, включая меня, имели такую ​​же проблему, например. here и here.