setNeedsDisplayInRect перерисовывает весь вид при использовании CATiledLayer - PullRequest
1 голос
/ 27 января 2010

это мой первый пост, поэтому прошу прощения за любые ошибки в этикете stackoverflow.

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

Я использую Кварц, и у меня есть CATiledLayer, на котором я нарисовал несколько прямоугольников, на которые вы можете нажать. Когда вы нажимаете один, я хочу перерисовать это поле с синим контуром, но не перерисовывать остальную часть представления. Из комментариев, которые я прочитал, кажется, что я должен использовать setNeedsDisplayInRect вместо setNeedsDisplay, как только я щелкну внутри границ одного из блоков, и установлю грязный прямоугольник на размер этого блока. Однако всякий раз, когда вызывается моя функция 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 и просто не могу заставить его делать то, что я хочу.

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

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

Ответы [ 2 ]

1 голос
/ 27 января 2010

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

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

0 голосов
/ 27 мая 2013

С Вопросы и ответы Apple : "весь вид будет перерисован, если вы позвоните -setNeedsDisplayInRect: или -setNeedsDisplay:."

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

Кажется, нет простого и понятного решения. Среди предложений - разбить ваше представление на несколько подпредставлений и запросить перерисовки только для тех, на кого это влияет, или отследить область для перерисовки самостоятельно.

У некоторых других, в том числе у меня, была такая же проблема, например, здесь и здесь .

...