我有一个带有自定义UIView
方法的drawRect:
子类,它会执行一些昂贵的计算来构建路径并使用CGContextStrokePath()
在当前上下文中绘制它。
如果我的视图的大小为(x, y)
,我想在(0, 0), (x/2, y)
上执行自定义绘图,然后使用上半部分的镜像图像填充(x/2, 0), (x, y)
区域。
除了手动复制要绘制的点之外,最简单/最快的方法是什么?也许将半视图渲染到位图图像上下文并使用该视图在当前图像上下文的两半上渲染?内容是动画的,因此drawRect:
大致每秒执行60次。
答案 0 :(得分:1)
执行此操作的一种有效方法是在CGLayer
的上下文上执行绘制操作,然后使用该图层绘制当前UIView
的上下文。
有关详细信息,请参阅Core Graphics Layer Drawing on the Quartz 2D Programming Guide。
基本上你会这样做:
- (void)drawRect:(CGRect)rect
{
const CGFloat viewWidth = view.bounds.size.width;
const CGFloat viewHeight = view.bounds.size.height;
CGContextRef viewContext = UIGraphicsGetCurrentContext();
CGLayerRef layer = CGLayerCreateWithContext(viewContext, CGSizeMake(viewWidth/2, viewHeight), 0);
CGContextRef layerContext = CGLayerGetContext(layer);
// Draw to the layerContext
// using CGContextStrokePath() or whatever
CGContextDrawLayerAtPoint(viewContext, CGPointZero, layer);
CGContextTranslateCTM(viewContext, viewWidth, 0);
CGContextScaleCTM(viewContext, -1, 1);
CGContextDrawLayerAtPoint(viewContext, CGPointZero, layer);
CGLayerRelease(layer);
}
此外,您可以将CGLayerRef
存储为UIView
的 ivar ,这样您就不会每帧都重新创建它。
这个解决方案在我的案例中效果很好,但有两点需要注意:
CGLayers
,如here所述。CGLayers
正确呈现视网膜屏幕,您必须遵循steps detailed here 答案 1 :(得分:0)
您可以计算CGPath
一次,您可以通过将整个路径构建为CGPath
而不是将其构建为CGContext
的一部分来执行此操作,或者您可以使用CGContextCopyPath
在上下文中创建CGPath
后获取CGPath
。然后你可以抚摸一次这条路。然后使用CGContext
将CGContextAddPath
重新放回CGContext
并更改(-1, 0, 0, 1, width, 0)
上的转换更改,以使您的镜像具有类似width
的转换,-1执行关于x轴的反射,{{1}}应该将其移回正确位置,并再次描边路径。