I'm trying to draw a UIBezierPath (f.e. 800x300) in a zoomable UIScrollView. After zooming is finished I'm adjusting the path's layer's scale value accordingly to draw a smooth path (otherwise it will be blurred). Everything went ok until I zoomed to a really high value (say 100x). After zooming the resulting layer which draws the path has a size of 80,000x30,000 an obviously it throws a warning in the console saying "Ignoring bogus layer size" and the drawRect is not called anymore and it is not drawn. It it were a regular image drawing, I would use CATiledLayer and would implement tiled drawing. But how to deal with the UIBezierPath drawing? What is the best/optimal way of drawing the path in such a big zoomable canvas (other than making an image from the path and implementing tiled drawing)?
0
votes
1 Answers
0
votes
Once the zoom breaks a certain threshold maybe draw to a UIImage. There you can apply the scale transform as below. Then transfer the image to the scrollview.
Here is a little test, it works both ways no problem.
@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