UIBezierPath Array rendering issue (How to use CGLayerRef for optimization)

只愿长相守 提交于 2019-12-11 18:49:36

问题


friends, I am working with UIBezierPaths, for free hand drawing , and everything works fine, for this I am storing my paths in a path array, everything works fine, while rendering, I am looping the whole array and rendering the paths,but soon as the array count increases, I see a lag while drawing, below is my drawRect code. please help me out in finding where I am going wrong

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

    UITouch *mytouch=[[touches allObjects] objectAtIndex:0];

    m_previousPoint2 = m_previousPoint1;
    m_previousPoint1 = [mytouch previousLocationInView:self];
    m_currentPoint = [mytouch locationInView:self];

    CGPoint mid1    = midPoint(m_previousPoint1, m_previousPoint2); 
    CGPoint mid2    = midPoint(m_currentPoint, m_previousPoint1);  

    testpath = CGPathCreateMutable();
    CGPathMoveToPoint(testpath, NULL, mid1.x, mid1.y);

    CGPathAddQuadCurveToPoint(testpath, NULL, m_previousPoint1.x, m_previousPoint1.y, mid2.x, mid2.y);      


    CGRect bounds = CGPathGetBoundingBox(testpath);   

    CGPathRelease(testpath);


    CGRect drawBox = bounds;

    //Pad our values so the bounding box respects our line width
    drawBox.origin.x        -= self.lineWidth * 2;
    drawBox.origin.y        -= self.lineWidth * 2;
    drawBox.size.width      += self.lineWidth * 4;
    drawBox.size.height     += self.lineWidth * 4;


    CGContextRef context = UIGraphicsGetCurrentContext();
    context = CGLayerGetContext(myLayerRef);


    [self.layer renderInContext:UIGraphicsGetCurrentContext()];      

    [self setNeedsDisplayInRect:drawBox];    

}


- (void)drawRect:(CGRect)rect
{   
    CGContextRef context = UIGraphicsGetCurrentContext();

    if(myLayerRef == nil)
    {            
        myLayerRef = CGLayerCreateWithContext(context, self.bounds.size, NULL);
    }

    [self.layer renderInContext:context];   


    CGPoint mid1 = midPoint(m_previousPoint1, m_previousPoint2); 
    CGPoint mid2 = midPoint(m_currentPoint, m_previousPoint1);


    CGContextMoveToPoint(context, mid1.x, mid1.y);
    CGContextAddQuadCurveToPoint(context, m_previousPoint1.x, m_previousPoint1.y, mid2.x, mid2.y); 
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineWidth(context, self.lineWidth);
    CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);

    CGContextSetFlatness(context, 0.1);

    CGContextSetAllowsAntialiasing(context, true);

    CGContextStrokePath(context);

    [super drawRect:rect];  

 }

Code updated according to the below discussion by @borrrden

Regards Ranjit


回答1:


There is an excellent session in the WWDC 2012 sessions about this exact problem. I think it is called iOS performance: Graphics or something similar. You should definitely watch it.

The summary is, DON'T store it in a path. There is no need to keep this path information around. Store a separate context (CGLayer is best) and draw into that (just like you add points to the path, add points to the context intead). Then in your drawRect, simply draw that layer into the current graphics context. Also be sure to only call setNeedsDisplay on the rectangle that changed, or you will most likely run into problems on a high resolution device.



来源:https://stackoverflow.com/questions/11312135/uibezierpath-array-rendering-issue-how-to-use-cglayerref-for-optimization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!