Not all tiles are redrawn after CATiledLayer -setNeedsDisplay

My view has it CATiledLayer. The view controller has custom zoom behavior, so -scrollViewDidEndZoomingyou need to redraw each fragment. But even if -setNeedsDisplaycalled at the level after each increase, not everyone is redrawn. This leads to the fact that the view sometimes seems wrong after scaling. (Things that should appear only in 1 tile appear in several places). He often corrects himself after another increase.

Here is the relevant code. updatedRectsDesigned for testing - it stores the unique rectangles requested for drawing -drawLayer.

CanvasView.h:

@interface CanvasView : UIView
@property (nonatomic, retain) NSMutableSet *updatedRects; 
@end

CanvasView.m:

@implementation CanvasView

@synthesize updatedRects; 

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

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context
{
    CGRect rect = CGContextGetClipBoundingBox(context); 
    [updatedRects addObject:[NSValue valueWithCGRect:rect]]; 

    CGContextSaveGState(context); 
    CGContextTranslateCTM(context, rect.origin.x, rect.origin.y); 
    // ...draw into context...
    CGContextRestoreGState(context); 
}

@end

MyViewController.m:

@implementation MyViewController

- (void)viewDidLoad 
{
    [super viewDidLoad];

    canvasView.updatedRects = [NSMutableSet set]; 
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
    canvasView.transform = CGAffineTransformIdentity; 
    canvasView.frame = CGRectMake(0, 0, canvasView.frame.size.width * scale, canvasView.frame.size.height); 
    [self updateCanvas]; 
}

- (void)updateCanvas
{
    NSLog(@"# rects updated: %d", [canvasView.updatedRects count]); 
    [canvasView.updatedRects removeAllObjects]; 
    canvasView.frame = CGRectMake(canvasView.frame.origin.x, canvasView.frame.origin.y, canvasView.frame.size.width, myHeight); 
    CGFloat tileSize = 256; 
    NSLog(@"next # rects updated will be: %f", [canvasView.layer bounds].size.width / tileSize); 
    [canvasView.layer setNeedsDisplay]; 
}

@end

, , , . , , " " , " " -updateCanvas. ?

:

. , updateCanvas, - canvasView. , x, (.), , (.) . , . , :

Screenshot of tiles with mismatched colorsScreenshot of tiles with mismatched colors

. , scrollViewDidEndZooming , , updateCanvas, . ( : -- .)

+3
1

, :

tiledLayer.contents = nil;
[tiledLayer setNeedsDisplayInRect:tiledLayer.bounds];

, , . , .

+10

Source: https://habr.com/ru/post/1796375/


All Articles