Last active
August 29, 2015 14:05
-
-
Save pronebird/c3dde8c25938c35c1ab8 to your computer and use it in GitHub Desktop.
Draw arrow with rounded corners using CoreGraphics
This file contains 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
@implementation UIImage (Arrow) | |
+ (UIImage*)arrowImageWithSize:(CGFloat)arrowSize withColor:(UIColor*)arrowColor thickness:(CGFloat)thickness | |
{ | |
// | |
// Create bezier path for arrow | |
// | |
// +---+-------+-+ | |
// | | | |
// | + | |
// | | | |
// + +-----+-+ | |
// | | | |
// | | | |
// + + | |
// | | | |
// +--+--+ | |
// | |
UIBezierPath *bezierPath = [UIBezierPath bezierPath]; | |
// Setup bezier path line width | |
bezierPath.lineWidth = 0.5f; | |
// Calculate radius | |
CGFloat radius = thickness * 0.5f; | |
// Top left | |
[bezierPath moveToPoint:CGPointMake(0, radius)]; | |
[bezierPath addQuadCurveToPoint:CGPointMake(radius, 0) controlPoint:CGPointMake(0, 0)]; | |
// Top right | |
[bezierPath addLineToPoint:CGPointMake(arrowSize - radius, 0)]; | |
[bezierPath addQuadCurveToPoint:CGPointMake(arrowSize, radius) controlPoint:CGPointMake(arrowSize, 0)]; | |
[bezierPath addQuadCurveToPoint:CGPointMake(arrowSize - radius, thickness) controlPoint:CGPointMake(arrowSize, thickness)]; | |
// Middle | |
[bezierPath addLineToPoint:CGPointMake(thickness + radius, thickness)]; | |
[bezierPath addQuadCurveToPoint:CGPointMake(thickness, thickness + radius) controlPoint:CGPointMake(thickness, thickness)]; | |
// Bottom right | |
[bezierPath addLineToPoint:CGPointMake(thickness, arrowSize - radius)]; | |
[bezierPath addQuadCurveToPoint:CGPointMake(radius, arrowSize) controlPoint:CGPointMake(thickness, arrowSize)]; | |
// Bottom left | |
[bezierPath addQuadCurveToPoint:CGPointMake(0, arrowSize - radius) controlPoint:CGPointMake(0, arrowSize)]; | |
// Close path | |
[bezierPath closePath]; | |
// Rotate bezierPath by 45 deg to get arrow to point north | |
CGFloat angle = 45 * M_PI/180; | |
// Create transformation matrix | |
CGAffineTransform transform = CGAffineTransformIdentity; | |
// Translate bezier path origin to its center to rotate around its center | |
transform = CGAffineTransformMakeTranslation(arrowSize * 0.5f, arrowSize * 0.5f); | |
// Rotate bezier path | |
transform = CGAffineTransformRotate(transform, angle); | |
// Apply transformation matrix | |
// This will calculated new bounds for bezier path | |
[bezierPath applyTransform:transform]; | |
// Undo translation | |
[bezierPath applyTransform:CGAffineTransformMakeTranslation(-bezierPath.bounds.origin.x, -bezierPath.bounds.origin.y)]; | |
// Get bounding rect of rotated bezierPath | |
CGRect arrowRect = CGRectZero; | |
arrowRect.size.width = ceil(CGRectGetWidth(bezierPath.bounds)); | |
arrowRect.size.height = ceil(CGRectGetHeight(bezierPath.bounds)); | |
// Create image context and draw bezier path | |
UIGraphicsBeginImageContextWithOptions(arrowRect.size, NO, 0.0f); | |
// Fill and stroke bezier path | |
[arrowColor setFill]; | |
[bezierPath fill]; | |
UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); | |
UIGraphicsEndImageContext(); | |
return image; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment