-1

我想像在 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}

先感谢您。

4

2 回答 2

1

您是否已经检查过文件名?

在搜索代码中的错误之前,只需检查图像的文件名:记住模拟器不区分大小写(FileName.png == filename.png -> 它将被加载)但 iDevice 区分大小写(FileName.png)。 png != filename.png -> 它不会被加载)

于 2012-06-27T09:51:58.980 回答
-1

问题在于图像不好(我使用在线转换器将图像从 jpg 转换为 png 并且遇到了困难,而不是使用 Photoshop 并且一切都变好了)

于 2012-06-27T10:41:03.217 回答