我想像在 PhotoScroller 应用程序中一样使用 CATiledLayer。在我的 TilingView.m 我有
+ (Class)layerClass {
return [CATiledLayer class];
}
- (id)initWithImageName:(NSString *)name size:(CGSize)size
{
if ((self = [super initWithFrame:CGRectMake(0, 0, size.width, size.height)])) {
imageName = [name retain];
CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
tiledLayer.levelsOfDetail = 4;
}
return self;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// get the scale from the context by getting the current transform matrix, then asking for
// its "a" component, which is one of the two scale components. We could also ask for "d".
// This assumes (safely) that the view is being scaled equally in both dimensions.
CGFloat scale = CGContextGetCTM(context).a;
CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
CGSize tileSize = tiledLayer.tileSize;
if (scale != 0.125)
{
UIImage *image = [UIImage imageNamed:imageName];
CGRect rect = self.bounds;
[image drawInRect:rect];
return;
}
// Even at scales lower than 100%, we are drawing into a rect in the coordinate system of the full
// image. One tile at 50% covers the width (in original image coordinates) of two tiles at 100%.
// So at 50% we need to stretch our tiles to double the width and height; at 25% we need to stretch
// them to quadruple the width and height; and so on.
// (Note that this means that we are drawing very blurry images as the scale gets low. At 12.5%,
// our lowest scale, we are stretching about 6 small tiles to fill the entire original image area.
// But this is okay, because the big blurry image we're drawing here will be scaled way down before
// it is displayed.)
tileSize.width /= scale;
tileSize.height /= scale;
// calculate the rows and columns of tiles that intersect the rect we have been asked to draw
int firstCol = floorf(CGRectGetMinX(rect) / tileSize.width);
int lastCol = floorf((CGRectGetMaxX(rect)-1) / tileSize.width);
int firstRow = floorf(CGRectGetMinY(rect) / tileSize.height);
int lastRow = floorf((CGRectGetMaxY(rect)-1) / tileSize.height);
for (int row = firstRow; row <= lastRow; row++) {
for (int col = firstCol; col <= lastCol; col++) {
UIImage *tile = [self tileForScale:scale row:row col:col];
CGRect tileRect = CGRectMake(tileSize.width * col, tileSize.height * row,
tileSize.width, tileSize.height);
// if the tile would stick outside of our bounds, we need to truncate it so as to avoid
// stretching out the partial tiles at the right and bottom edges
tileRect = CGRectIntersection(self.bounds, tileRect);
[tile drawInRect:tileRect];
if (self.annotates) {
[[UIColor whiteColor] set];
CGContextSetLineWidth(context, 6.0 / scale);
CGContextStrokeRect(context, tileRect);
}
}
}
}
所以,当我使用视网膜显示器时,它总是进入
if (scale != 0.125)
{
UIImage *image = [UIImage imageNamed:imageName];
CGRect rect = self.bounds;
[image drawInRect:rect];
return;
}
它在模拟器(视网膜显示器)上完美运行,但在设备上它会引发异常(图像!= nil,我已经检查过)
[image drawInRect:rect];
例外
0x35affc70: push {r4, r5, r6, r7, lr}
0x35affc72: add r7, sp, #12
0x35affc74: push.w {r8, r10, r11}
0x35affc78: ldr r1, [r0]
0x35affc7a: ldr r2, [r0, #12]
0x35affc7c: cmp.w r2, r1, lsl #2
0x35affc80: blo 0x35affd06 ; ImageIO_ABGR_TO_ARGB_8Bit + 150
0x35affc82: ldr r3, [r0, #24]
0x35affc84: lsls r2, r1, #2
0x35affc86: cmp r3, r2
0x35affc88: blo 0x35affd06 ; ImageIO_ABGR_TO_ARGB_8Bit + 150
0x35affc8a: ldr r2, [r0, #4]
0x35affc8c: cmp r2, #0
0x35affc8e: beq 0x35affd06 ; ImageIO_ABGR_TO_ARGB_8Bit + 150
0x35affc90: bic lr, r1, #7
0x35affc94: ldr r3, [r0, #8]
0x35affc96: ldr.w r12, [r0, #20]
0x35affc9a: sub.w r4, r1, lr
0x35affc9e: asrs r5, r1, #3
0x35affca0: mov r6, r12
0x35affca2: mov r8, r3
0x35affca4: cbz r5, 0x35affcbe ; ImageIO_ABGR_TO_ARGB_8Bit + 78
0x35affca6: mov r8, r3
0x35affca8: mov r9, r5
0x35affcaa: mov r6, r12
0x35affcac: vld4.8 {d0, d1, d2, d3}, [r8]!
0x35affcb0: vswp d0, d2
0x35affcb4: vst4.8 {d0, d1, d2, d3}, [r6]! ;!!!!!!!!string with exception!!!!!!!!!!!!
0x35affcb8: subs.w r9, r9, #1
0x35affcbc: bne 0x35affeac ; slab_dealloc + 132
0x35affcbe: cmp lr, r1
0x35affcc0: bge 0x35affcf8 ; ImageIO_ABGR_TO_ARGB_8Bit + 136
0x35affcc2: add.w r8, r8, #2
0x35affcc6: adds r6, #2
0x35affcc8: mov r9, r4
0x35affcca: ldrb.w r11, [r8]
0x35affcce: subs.w r9, r9, #1
0x35affcd2: ldrb r10, [r8, #-2]
0x35affcd6: strb r11, [r6, #-2]
0x35affcda: ldrb r11, [r8, #-1]
0x35affcde: strb r11, [r6, #-1]
0x35affce2: strb.w r10, [r6]
0x35affce6: ldrb.w r10, [r8, #1]
0x35affcea: add.w r8, r8, #4
0x35affcee: strb.w r10, [r6, #1]
0x35affcf2: add.w r6, r6, #4
0x35affcf6: bne 0x35affeca ; current_timestamp + 26
0x35affcf8: ldr r6, [r0, #12]
0x35affcfa: subs r2, #1
0x35affcfc: ldr.w r8, [r0, #24]
0x35affd00: add r3, r6
0x35affd02: add r12, r8
0x35affd04: bne 0x35affea0 ; slab_dealloc + 120
0x35affd06: pop.w {r8, r10, r11}
0x35affd0a: pop {r4, r5, r6, r7, pc}
先感谢您。