Created
February 14, 2012 21:55
-
-
Save ksm/1830844 to your computer and use it in GitHub Desktop.
CoreGraphics UITableView iOS5 bevel effect function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Copied and pasted from Tim Oliver's blog. | |
Source: http://www.tim-oliver.com/2011/10/23/creating-the-uitableview-bevel-effect-in-coregraphics/ | |
*/ | |
void DrawInsetBeveledRoundedRect(CGContextRef context, CGRect rect, CGFloat radius, UIColor *fillColor) { | |
//contract the bounds of the rectangle in to account for the stroke | |
CGRect drawRect = CGRectInset(rect, 1.0f, 1.0f); | |
//contract the height by 1 to account for the white bevel at the bottom | |
drawRect.size.height -= 1.0f; | |
//Save the current state so we don't persist anything beyond this operation | |
CGContextSaveGState(context); | |
//Generate the rounded rectangle paths | |
CGPathRef boxPath = [[UIBezierPath bezierPathWithRoundedRect: drawRect cornerRadius: radius] CGPath]; | |
//For the stroke, offset by half a pixel to ensure proper drawing | |
CGPathRef strokePath = [[UIBezierPath bezierPathWithRoundedRect: CGRectInset(drawRect, -0.5f, -0.5f) cornerRadius: radius] CGPath]; | |
/*Draw the bevel effect*/ | |
CGContextSaveGState(context); | |
//Set the color to be slightly transparent white | |
CGContextSetFillColorWithColor(context, [[UIColor colorWithWhite: 1.0f alpha: 0.8f] CGColor]); | |
//Clip the region to only the visible portion to optimzie drawing | |
CGContextClipToRect(context, CGRectMake(rect.origin.x, rect.origin.y+rect.size.height-radius, rect.size.width, radius)); | |
//draw the left corner curve | |
CGRect corner = CGRectMake(rect.origin.x, (rect.origin.y+rect.size.height)-(2*radius)-1, (radius*2)+1, (radius*2)+1); | |
CGContextFillEllipseInRect(context, corner); | |
//draw the right corner | |
corner.origin.x = rect.origin.x + rect.size.width - (radius*2)-1; | |
CGContextFillEllipseInRect(context, corner); | |
//draw the rectangle in the middle | |
//set the blend mode to replace any existing pixels (or else we'll see visible overlap) | |
CGContextSetBlendMode(context, kCGBlendModeCopy); | |
CGContextFillRect(context, CGRectMake(rect.origin.x+radius, rect.origin.y+rect.size.height-radius, rect.size.width-(2*radius),radius+1)); | |
CGContextRestoreGState(context); | |
/*Draw the main region */ | |
CGContextSaveGState(context); | |
//fill it with our colour of choice | |
CGContextSetFillColorWithColor(context, [fillColor CGColor]); | |
//use the stroke path so the boundaries line up with the stroke (else we'll see a gap on retina devices) | |
CGContextAddPath(context, strokePath); | |
//fill it | |
CGContextFillPath(context); | |
CGContextRestoreGState(context); | |
/*Main fill region inner drop shadow*/ | |
/*(This is done by duplicating the path, offsetting the duplicate by 1 pixel, and using the EO winding fill rule to fill the gap between the two)*/ | |
CGContextSaveGState(context); | |
//set the colour to be a VERY faint grey | |
CGContextSetFillColorWithColor(context, [[UIColor colorWithWhite: 0.0f alpha: 0.08f] CGColor]); | |
//clip the shadow to the top of the box (to reduce overhead) | |
CGContextClipToRect(context, CGRectMake( drawRect.origin.x, drawRect.origin.y, drawRect.size.width, radius )); | |
//add the first instance of the path | |
CGContextAddPath(context, boxPath); | |
//translate the draw origin down by 1 pixel | |
CGContextTranslateCTM(context, 0.0f, 1.0f); | |
//add the second instance of the path | |
CGContextAddPath(context, boxPath); | |
//use the EO winding rule to fill the gap between the two paths | |
CGContextEOFillPath(context); | |
CGContextRestoreGState(context); | |
/*Outer Stroke*/ | |
/*This is drawn outside of the fill region to prevent the fill region bleeding over in some cases*/ | |
CGContextSaveGState(context); | |
//set the line width to be 1 pixel | |
CGContextSetLineWidth(context, 1.0f); | |
//set the the colour to be a very transparent shade of grey | |
CGContextSetStrokeColorWithColor(context, [[UIColor colorWithWhite: 0.0f alpha: 0.18f] CGColor]); | |
//set up the path to draw the stroke along | |
CGContextAddPath(context, strokePath); | |
//set the blending mode to replace underlying pixels on this layer (so the background will come through through) | |
CGContextSetBlendMode(context, kCGBlendModeCopy); | |
//draw the path | |
CGContextStrokePath(context); | |
CGContextRestoreGState(context); | |
//Restore the previous CG state | |
CGContextRestoreGState(context); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment