the_critic
the_critic

Reputation: 12820

Questions regarding drawing in iOS

I want to create a little navigation bar on the bottom of my iPhone screen where I basically just draw 5 rectangles next to each other. However, only the active page should have the opacity of 1.0 and others should be slightly transparent (alpha=0.4). That is what I already have.

Now my questions:

I have very little experience with drawing, so I am a little lost there. I have read the documentation of Quartz2d and contexts, but still, as I mentioned I have not fully figured out how it works.

Here is some code I use:

-(void)drawRect:(CGRect)rect{

    CGContextRef context = UIGraphicsGetCurrentContext();
    //save state
    CGContextSaveGState(context);

    //NAV1
    CGMutablePathRef nav1 = CGPathCreateMutable();
    CGPathAddRect(nav1, NULL, CGRectMake(0 , 15, 64, 10));
    UIColor *blueColor = UIColorFromRGB(0x35BFE5,0.1);
    CGColorRef bC = [blueColor CGColor];
    [colorArray addObject:(__bridge id)bC];
    [navArray addObject:(__bridge id)nav1];
    CGPathRelease(nav1);
    /*
     *
     *
     ... I do this for all 5 navigation elements

     *
     *
     */

    //then I go through all my rectangles and add/fill them
    for(int i=0;i<[navArray count];i++){
        CGContextAddPath(context, (__bridge CGMutablePathRef)[navArray objectAtIndex:i]);
        CGContextSetFillColorWithColor(context, (__bridge CGColorRef)[colorArray objectAtIndex:i]);
        CGContextFillPath(context);

    }

    // restore to last saved context state 
    CGContextRestoreGState(context);
}

//and this is how I redraw
-(void)updateActiveNav{
    [navArray removeAllObjects];
    [colorArray removeAllObjects];
    [self setNeedsDisplay];
}

Upvotes: 2

Views: 163

Answers (2)

Guillaume
Guillaume

Reputation: 4361

If you actually draw the interface, you will have to redraw it whenever it changes, at least the rectangles that change. You can reuse CGPaths, but they aren't graphical objects on screen, they are just instructions on how to draw shapes, so you will have to draw everything again.

That being said, you can use individual UIViews instead, which represent onscreen objects, and you can change their opacity, which will reflect on screen.

Upvotes: 1

Ryan Poolos
Ryan Poolos

Reputation: 18551

This is the problem:

for(int i=0;i<[navArray count];i++){
        CGContextAddPath(context, (__bridge CGMutablePathRef)[navArray objectAtIndex:i]);
        CGContextSetFillColorWithColor(context, (__bridge CGColorRef)[colorArray objectAtIndex:i]);
        CGContextFillPath(context);

    }

You are added the path to your context, then setting a fill color, then filling it. Then without restoring your context you're doing it again so your filling the previous path and the new one. Its not the drawing from the last drawRect its the drawing from here. Try something like below so that after you fill the path you reset the context and draw the next block by itself instead of both the 1st and 2nd etc.

for(int i=0;i<[navArray count];i++){
    CGContextSaveGState(context);
    // Add Path, Fill
    CGContextRestoreGState(context);
}

Upvotes: 1

Related Questions