Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6792101
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T17:55:38+00:00 2026-05-26T17:55:38+00:00

This Is a problem that I’ve been leaving and coming back to for a

  • 0

This Is a problem that I’ve been leaving and coming back to for a while now. I’ve never really nailed the problem.

What I’ve been trying to do use CADisplayLink to dynamically draw pie chart style progress. My code works fine when I have 1 – 4 uiviews updating simultaneously. When I add any more than that the drawing of the pies becomes very jerky.

I want to explain what I have been trying in the hope that somebody could point out the inefficiencies and suggest a better drawing method.

I create 16 uiviews and add a CAShapeLayer subview to each one. This is where I want to draw my pie slices.

I precalcuate 360 CGPaths representing 0 to 360 degrees of a circle and store them in an array to try and improve performance.

In a master View I start a displaylink,loop through all my other views, calculate how much of a full pie it should show, then find the right path and assign it to my shapelayer.

-(void)makepieslices
{
    pies=[[NSMutableArray alloc]initWithCapacity:360];
    float progress=0;
    for(int i=0;i<=360;i++)

    {
        progress= (i* M_PI)/180;
        CGMutablePathRef thePath = CGPathCreateMutable();
        CGPathMoveToPoint(thePath, NULL, 0.f, 0.f);
        CGPathAddLineToPoint(thePath, NULL, 28, 0.f);
        CGPathAddArc(thePath, NULL, 0.f,0.f, 28, 0.f, progress, NO);
        CGPathCloseSubpath(thePath);
        _pies[i]=thePath;


    }



}

- (void)updatePath:(CADisplayLink *)dLink {

    for (int idx=0; idx<[spinnydelegates count]; idx++) {

        id<SyncSpinUpdateDelegate> delegate = [spinnydelegates objectAtIndex:idx];
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [delegate updatePath:dLink];
        });

    }






}

- (void)updatePath:(CADisplayLink *)dLink {

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        currentarc=[engineref getsyncpercentForPad:cid pad:pid];

        int progress;

        progress = roundf(currentarc*360);

        dispatch_async(dispatch_get_main_queue(), ^{
            shapeLayer_.path = _pies[progress];

        });



    });


}

This technique just straight out isnt working for me when trying to simultaneously update more than 4 or 5 pies at the same time. 16 screen updates at the same time sounds like it should really not be that big of a deal for the ipad to me. So this leads me to think I doing something very very fundamentally wrong.

I’d really appreciate if somebody could tell me why this technique results in jittery screen updates and also if they could suggest a different technique that I could go an investigate that will allow me to perform 16 simultaneous shapelayer updates smoothly.

EDIT Just to give you an idea of how bad performance is, when I have all 16 pies drawing the cpu goes up to 20%

*EDIT *

This is based on studevs advice but I don’t see anything been drawn. segmentLayer is a CGLayerRef as a property of my pieview.

-(void)makepies
{

    self.layerobjects=[NSMutableArray arrayWithCapacity:360];

    CGFloat progress=0;

    CGContextRef context=UIGraphicsGetCurrentContext();

    for(int i =0;i<360;i++)
    {
        progress= (i*M_PI)/180.0f;

        CGLayerRef segmentlayer=CGLayerCreateWithContext(context, CGSizeMake(30, 30), NULL);
        CGContextRef layerContext=CGLayerGetContext(segmentlayer);
        CGMutablePathRef thePath = CGPathCreateMutable();
        CGPathMoveToPoint(thePath, NULL, 0.f, 0.f);
        CGPathAddLineToPoint(thePath, NULL, 28, 0.f);
        CGPathAddArc(thePath, NULL, 0.f,0.f, 28, 0.f, progress, NO);
        CGPathCloseSubpath(thePath);

        [layerobjects addObject:(id)segmentlayer];
        CGLayerRelease(segmentlayer);
    }

}



-(void)updatePath
{
    int progress;

    currentarc=[engineref getsyncpercent];
    progress = roundf(currentarc*360);


    //shapeLayer_.path = _pies[progress];

    self.pieView.segmentLayer=(CGLayerRef)[layerobjects objectAtIndex:progress];

    [self.pieView setNeedsDisplay];


}

-(void)drawRect:(CGRect)rect
{

    CGContextRef context=UIGraphicsGetCurrentContext();

    CGContextDrawLayerInRect(context, self.bounds, segmentLayer);

}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T17:55:39+00:00Added an answer on May 26, 2026 at 5:55 pm

    I think one of the first things you should look to do is buffer your segments (currently represented by CGPath objects) offscreen using CGLayer objects. From the docs:

    Layers are suited for the following:

    • High-quality offscreen rendering of drawing that you plan to reuse.
      For example, you might be building a scene and plan to reuse the same
      background. Draw the background scene to a layer and then draw the
      layer whenever you need it. One added benefit is that you don’t need
      to know color space or device-dependent information to draw to a
      layer.

    • Repeated drawing. For example, you might want to create a
      pattern that consists of the same item drawn over and over. Draw the
      item to a layer and then repeatedly draw the layer, as shown in Figure
      12-1. Any Quartz object that you draw repeatedly—including CGPath,
      CGShading, and CGPDFPage objects—benefits from improved performance if
      you draw it to a CGLayer. Note that a layer is not just for onscreen
      drawing; you can use it for graphics contexts that aren’t
      screen-oriented, such as a PDF graphics context.

    Create a UIView subclass that draws the pie. Give it an instance variable for that pie’s current progress, and override drawRect: to draw the layer representing that progress. The view needs to first get a reference the required CGLayer object, so implement a delegate with the method:

    - (CGLayerRef)pieView:(PieView *)pieView segmentLayerForProgress:(NSInteger)progress context:(CGContextRef)context;
    

    It will then become the delegate’s job to return an existing CGLayerRef, or if it doesn’t exist yet, create it. Since the CGLayer can only be created from within drawRect:, this delegate method should be called from PieView‘s drawRect: method. PieView should look something like this:

    PieView.h

    #import <UIKit/UIKit.h>
    #import <QuartzCore/QuartzCore.h>
    
    
    @class PieView;
    
    @protocol PieViewDelegate <NSObject>
    
    @required
    - (CGLayerRef)pieView:(PieView *)pieView segmentLayerForProgress:(NSInteger)progress context:(CGContextRef)context;
    
    @end
    
    
    @interface PieView : UIView
    
    @property(nonatomic, weak) id <PieViewDelegate> delegate;
    @property(nonatomic) NSInteger progress;
    
    @end
    

    PieView.m

    #import "PieView.h"
    
    
    @implementation PieView
    
    @synthesize delegate, progress;
    
    - (void)drawRect:(CGRect)rect
    {
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGLayerRef segmentLayer = [delegate pieView:self segmentLayerForProgress:self.progress context:context];
        CGContextDrawLayerInRect(context, self.bounds, segmentLayer);
    }
    
    @end
    

    Your PieView‘s delegate (most likely your view controller) then implements:

    NSString *const SegmentCacheKey = @"SegmentForProgress:";
    
    - (CGLayerRef)pieView:(PieView *)pieView segmentLayerForProgress:(NSInteger)progress context:(CGContextRef)context
    {
        // First, try to retrieve the layer from the cache
        NSString *cacheKey = [SegmentCacheKey stringByAppendingFormat:@"%d", progress];
        CGLayerRef segmentLayer = (__bridge_retained CGLayerRef)[segmentsCache objectForKey:cacheKey];
    
        if (!segmentLayer) {    // If the layer hasn't been created yet
            CGFloat progressAngle = (progress * M_PI) / 180.0f;
    
            // Create the layer
            segmentLayer = CGLayerCreateWithContext(context, layerSize, NULL);
            CGContextRef layerContext = CGLayerGetContext(segmentLayer);
    
            // Draw the segment
            CGContextSetFillColorWithColor(layerContext, [[UIColor blueColor] CGColor]);
            CGContextMoveToPoint(layerContext, layerSize.width / 2.0f, layerSize.height / 2.0f);
            CGContextAddArc(layerContext, layerSize.width / 2.0f, layerSize.height / 2.0f, layerSize.width / 2.0f, 0.0f, progressAngle, NO);
            CGContextClosePath(layerContext);
            CGContextFillPath(layerContext);
    
            // Cache the layer
            [segmentsCache setObject:(__bridge_transfer id)segmentLayer forKey:cacheKey];
        }
    
        return segmentLayer;
    }
    

    So for each pie, create a new PieView and set it’s delegate. When you need to update a pie, update the PieView‘s progress property and call setNeedsDisplay.

    I’m using an NSCache here since there are a lot of graphics being stored, and it could take up a lot of memory. You could also limit the number of segments being drawn – 100 is probably plenty. Also, I agree with other comments/answers that you might try updating the views less often, as this will consume less CPU and battery power (60fps is probably not necessary).


    I did some crude testing of this method on an iPad (1st gen) and managed to get well over 50 pies updating at 30fps.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Ok I have this problem that I've never had before, it's really bugging me.
This is a really weird problem that I have been having. When I download
This is a problem that has been eating at me for a while, and
There was this problem that has been asked about implementing a load byte into
THIRD EDIT: I now believe that this problem is due to a SOAP version
This has been a problem that I haven't been able to figure out for
Edit : The bug that caused this problem has been fixed. The @version tag
I've been having this problem that I just can't wrap my mind around. I
This is an interesting problem that I’ve not been able to solve yet. I
We use SharpSVN to programmatically access SVN repositories. Now we have the problem that

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.