简体   繁体   中英

Drawing UIBezierPath in a UIScrollView

I'm trying to draw a UIBezierPath (fe 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)?

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

Storyboard for reference在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM