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

  • Home
  • SEARCH
  • 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 7841021
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 2, 20262026-06-02T16:00:25+00:00 2026-06-02T16:00:25+00:00

I am using Quartz 2D to make a simple multi-touch drawing iPad game. The

  • 0

I am using Quartz 2D to make a simple multi-touch drawing iPad game. The game requires me to draw a new stroke at the finger position every 1/30th of a second.

As far as I know, there is basically no way to get drawRect() to not clear the context every time it is called (self.clearsContextBeforeDrawing = NO; does not work), so my solution was to create a back buffer bitmap (or layer, I can use both), draw every new small stroke into that back buffer every iteration for each finger, and then copy the buffer into the screen every call to drawRect(). In other words:

backlayer = CGLayerCreateWithContext(context, CGSizeMake(W, H), NULL);
offctx = CGLayerGetContext (backlayer); 

and then

- (void)drawRect:(CGRect)rect
{

    CGContextRef context = UIGraphicsGetCurrentContext();

    //code here to draw small strokes from old finger position to new one

    CGContextDrawLayerInRect(context, [self bounds], backlayer);
}

This worked without problems while I was testing on my iPad 2, but yesterday I noticed that this same code runs much slower on the new iPad 3. The performance is abysmal, slowing my game down from 30FPS all the way to about 5 or so, probably due to the larger, retina display. I have the same problem if I use a separate CGBitmapContext that I create, and then every iteration I create an ImageRef from it and paint it with CGContextDrawImage.

What approach could I take to address this? It seems like I must redraw everything every iteration since it’s not good enough to even pass a small rectange to drawRect of what has changed (since every iteration there would need to be several rectangles for each finger)

Thank you

  • 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-06-02T16:00:26+00:00Added an answer on June 2, 2026 at 4:00 pm

    I managed to resolve this as follows:

    I create a new UIView subclass header and implementation files:

    @interface fingerView : UIView {
    }
    

    Then in my main view, in header I declare 5 of these views:

    fingerView* fview[5];
    

    and in my main view implementation I create 5 views of this instance, one for each finger separately. Also, must make sure to make them, enable multitouch for each of them, and make sure that clearsContextBeforeDrawing is set to NO, as we will be updating tiny rects in each of them at a time, and we dont want the system to clear our work.

    for(int i=0;i<5;i++) {
            fview[i] = [[pView alloc] initWithFrame:topFrame];
            [self addSubview: fview[i]];
            [self sendSubviewToBack: fview[i]];
            fview[i].opaque= NO;
            fview[i].clearsContextBeforeDrawing = NO;
            fview[i].multipleTouchEnabled = YES;
    }
    

    Now inside every finger view keep a large array (i use a simple array, say 10,000 long) of x and y positions that the finger had drawn on. Whenever a finger moves, the main view detects it, and calls a [fview[i] updatePos(newx, newy)], and crucially, we will command the view to only update a tiny potion of itself around these coordinates:

    [fview[i] setNeedsDisplayInRect: fingerRect];
    

    where fingerRect is a small rect centered at (newx, newy). Inside the drawRect method for every finger view,

    - (void)drawRect:(CGRect)rect
    {
        if (movep==0) return;
    
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetRGBStrokeColor(context, r, g, b, 1);
        CGContextSetLineWidth(context, linewidth);
    
        //paint finger
        CGContextBeginPath(context);
        CGFloat slack= 15;
        CGFloat minx= CGRectGetMinX(rect)-slack;
        CGFloat maxx= CGRectGetMaxX(rect)+slack;
        CGFloat miny= CGRectGetMinY(rect)-slack;
        CGFloat maxy= CGRectGetMaxY(rect)+slack;    
        bool drawing = NO;
        for(int i=0;i<movep;i++) {
            CGFloat xx= x[i];
            CGFloat yy= y[i];
            if(xx>minx && xx<maxx && yy>miny && yy<maxy) {
    
                if(drawing) {
    
                    // continue line
                    CGContextAddLineToPoint(context, xx, yy);
                    CGContextMoveToPoint(context, xx, yy);
    
                } else {
    
                    // start drawing
                    CGContextMoveToPoint(context, xx, yy);
                    drawing= YES;
                }
    
            } else {
                drawing= NO;  
            }
        }
    
        CGContextStrokePath(context);
    

    and also, as I mentioned

    - (void)updatePos: (CGFloat)xnew: (CGFloat) ynew
    {
        x[movep]= xnew;
        y[movep]= ynew;
        movep= movep+1;
    

    Hopefully you can figure out how this works. Every view will look into this rectangle that has been modified, and checks all finger positions that went around that rect, and only draws those. This will come down to very few strokes, and so the entire code runs very fast.

    The lesson overall is that UIViews are extremely optimized. As much as possible, try to make a whole bunch of them, update them only locally if at all, and let Apple’s magic blend it all together.

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

Sidebar

Related Questions

it is a interesting question. i am using Quartz.net to make job scheduler. also
I'm making a complex drawing using quartz based on passed in information. The only
Using a scaling transform to negate the y-coordinate alters some conventions in Quartz drawing
I am trying to draw a string using quartz 2d. What i am doing
I am using quartz 2d to draw a pie chart. I use layer to
I'm currently drawing a sinus-curve using the CoreGraphics/Quartz CGContextAddLineToPoint-function on the iPhone: CGContextRef _context
I have witten an iPhone game using Quartz 2d. It works fine all devices
I am using quartz.net to schedule regular events within asp.net mvc application. The scheduled
I'm using Quartz in my .NET application. At first, I was using it in
I developed an EAR using Quartz API. I have put my quartz.properties file in

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.