在 UIScrollView 中绘制 UIBezierPath
Posted
技术标签:
【中文标题】在 UIScrollView 中绘制 UIBezierPath【英文标题】:Drawing UIBezierPath in a UIScrollView 【发布时间】:2021-02-13 15:22:44 【问题描述】:我正在尝试在 可缩放 UIScrollView 中绘制 UIBezierPath(例如 800x300)。缩放完成后,我正在相应地调整路径图层的比例值以绘制平滑路径(否则会模糊)。 一切都很顺利,直到我放大到一个非常高的值(比如 100 倍)。缩放后绘制路径的结果层的大小为 80,000x30,000,显然它会在控制台中引发警告说“忽略虚假层大小”,并且不再调用 drawRect 并且它没有被绘制。这是一个常规的图像绘制,我会使用 CATiledLayer 并实现平铺绘制。但是如何处理 UIBezierPath 绘制呢?在如此大的可缩放画布中绘制路径的最佳/最佳方式是什么(从路径制作图像并实现平铺绘图除外)?
【问题讨论】:
看看 Adam Wulf's Open Source on Github 特别是他的 PerformanceBezier 项目 【参考方案1】:一旦缩放突破某个阈值,可能会绘制到 UIImage。在那里,您可以应用如下比例变换。然后将图像传输到滚动视图。
这是一个小测试,它可以双向工作。
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView * zoomImage;
@property (weak, nonatomic) IBOutlet UILabel * zoomLabel;
@property (nonatomic) CGFloat zoomFactor;
@end
@implementation ViewController
// Bezier path
// Draws a little cross
- ( void ) drawIt:( CGContextRef ) cr
CGContextBeginPath( cr );
CGContextMoveToPoint( cr, 0, 0 );
CGContextAddLineToPoint( cr, 10, 10 );
CGContextMoveToPoint( cr, 0, 10 );
CGContextAddLineToPoint( cr, 10, 0 );
CGContextClosePath( cr );
CGContextStrokePath( cr );
- ( void ) setZoomFactor:( CGFloat ) zoomFactor
_zoomFactor = zoomFactor;
self.zoomLabel.text = [NSString stringWithFormat:@"Now %f", zoomFactor];
CGSize srcSz = CGSizeMake ( 10 * zoomFactor, 10 * zoomFactor );
CGSize dstSz = self.zoomImage.bounds.size;
// Aspect ratio
CGFloat sx = dstSz.width / srcSz.width;
CGFloat sy = dstSz.height / srcSz.height;
self.zoomImage.image = [[[UIGraphicsImageRenderer alloc] initWithSize:dstSz] imageWithActions: ^ ( UIGraphicsImageRendererContext * ctx )
CGContextRef cr = ctx.CGContext;
// Aspect
if ( sx < sy )
CGContextScaleCTM ( cr, sx, sx );
else
CGContextScaleCTM ( cr, sy, sy );
// Offset
CGContextTranslateCTM ( cr, srcSz.width / 2 - 5, srcSz.height / 2 - 5 );
// Draw
[self drawIt:cr];
];
- ( void ) viewDidAppear:( BOOL ) animated
[super viewDidAppear:animated];
if ( ! self.zoomFactor )
self.zoomFactor = 1;
- ( IBAction ) zoomInButtonAction:( id ) sender
if ( self.zoomFactor > 1e-12 )
self.zoomFactor /= 2;
- ( IBAction ) zoomOutButtonAction:( id ) sender
if ( self.zoomFactor < 1e12 )
self.zoomFactor *= 2;
@end
故事板供参考
【讨论】:
从图层创建 uiimage 不会提供最佳性能,尤其是当有许多图层绘制路径时 我认为您的性能问题与滚动视图中的相同?以上是关于在 UIScrollView 中绘制 UIBezierPath的主要内容,如果未能解决你的问题,请参考以下文章
目标 C:在 UIScrollView 中触摸时绘制(写入)