gpt4 book ai didi

iphone - CATiledLayer绘图崩溃

转载 作者:行者123 更新时间:2023-12-03 03:27:30 25 4
gpt4 key购买 nike

在我的应用程序中,我使用的 View 层次结构如下:

UIView
----UIScrollView
--------TiledView (UIView subclass, uses CATiledLayer for drawing)
----OverlayView (UIView subclass)

简而言之 - TiledView 显示大平铺图像我还将自定义旋转应用于该 View :

tiledView.transform = CGAffineTransformMakeRotation(angle);

TiledView的绘制方法:

- (void)drawRect:(CGRect)rect {
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
...
NSString *fileName = [NSString stringWithFormat:@"tile_%d_%d.jpg", y + 1, x + 1];
UIImage *image = [UIImage imageNamed:fileName];
[image drawInRect:rect];
}

UIScrollView 允许滚动和缩放其内容。
Overlay View 位于 UIScrollView 之上,具有透明背景并执行一些自定义绘图。我使用单独的 View 来确保线宽和字体大小不受 ScrollView 中缩放比例的影响。

OverlayView的绘制方法:

- (void)drawRect:(CGRect)rect {
// Drawing code
[super drawRect:rect];

// Custom drawing code
CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetRGBStrokeColor(context, 1.0, 1.0, 0, 1);
CGContextSetLineWidth(context, lineWidth);

CGContextBeginPath(context);
CGContextMoveToPoint(context, (int)startPoint.x,(int) startPoint.y);

if (usesMidPoint)
CGContextAddLineToPoint(context, (int)midPoint.x, (int)midPoint.y);
CGContextAddLineToPoint(context, endPoint.x, endPoint.y);

CGContextStrokePath(context);
}

最初一切正常,但在对 View 进行一些操作(例如来回滚动等)后,它在绘图函数之一的某些随机线上崩溃。作为示例应用程序在线崩溃:

CGContextSetRGBStrokeColor(context, 1.0, 1.0, 0, 1); 

带堆栈:

#0  0x00503088 in CGColorEqualToColor
#1 0x00505430 in CGGStateSetStrokeColor
#2 0x005053b6 in setStrokeColorWithComponents
#3 0x0056150f in CGContextSetRGBStrokeColor
#4 0x000764ab in -[GADrawView drawRect:] at GADrawView.m:38
#5 0x016a7a78 in -[UIView(CALayerDelegate) drawLayer:inContext:]
#6 0x0077c007 in -[CALayer drawInContext:]

我是否缺少多个图形上下文之间所需的任何同步?或者可能有更好的方法来做我正在尝试的事情?

最佳答案

找到问题的解决方案。如 Apple technical note 中所述CATiledLayer 使用单独的线程来获取其图 block 的内容:

The CATiledLayer implements its drawing by using a background thread to fetch the contents of each tile, however the drawing functions provided by UIKit rely on a global context stack, and as such when a CATiledLayer starts rendering, using any of UIKit's drawing functions can result in a race condition.

因此,解决方案是将所有绘图代码从 -drawRect: 方法移至 -drawLayer:inContext:使用 Core Graphics 进行绘制功能。使用 CoreGraphics 绘图还需要在坐标系之间进行一些转换 - 这 post来自苹果论坛的人帮助了他们(请参阅drawLayer:方法实现)。

所以 TiledView 的正确绘制代码:

- (void)drawRect:(CGRect)rect {
//Still need to have this method implemented even if its empty!
}

-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx
{
// Do all your drawing here. Do not use UIGraphics to do any drawing, use Core Graphics instead.
// convert the CA coordinate system to the iPhone coordinate system
CGContextTranslateCTM(ctx, 0.0f, 0.0f);
CGContextScaleCTM(ctx, 1.0f, -1.0f);

CGRect box = CGContextGetClipBoundingBox(ctx);

// invert the Y-coord to translate between CA coords and iPhone coords
CGPoint pixelTopLeft = CGPointApplyAffineTransform(box.origin, CGAffineTransformMakeScale(1.0f, -1.0f));

NSString *tileUrlString = [self urlForPoint:pixelTopLeft];

UIImage *image = [UIImage imageNamed:tileUrlString];
CGContextDrawImage(ctx, box, [image CGImage]);
}

关于iphone - CATiledLayer绘图崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2295151/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com