You can find all the details and some raw Obj-C code here (gist). The code isn't complete but enough to start.
Here only draw background image code:
- (UIImage*)hintImage {
CGMutablePathRef path = CGPathCreateMutable();
CGPoint p = CGPointMake(__PADDING_X, __PADDING_Y);
CGPoint p1 = CGPointZero;
CGPoint p2 = CGPointZero;
//1
p.x += __PAN_UPPER_RADIUS;
CGPathMoveToPoint(path, NULL, p.x, p.y);
NSUInteger hintCount = [self.hintSymbolsList count];
//!!!:magic numbers
self.hintAdditionalWidth = 2*(hintCount-1)*(self.frame.size.width+__GAP_X);
//2
p.x += __PAN_UPPDER_WIDTH + self.hintAdditionalWidth;
//!!!:+hintCount*(__PAN_LOWER_WIDTH+__GAP_X);
CGPathAddLineToPoint(path, NULL, p.x, p.y);
//3
p.y += __PAN_UPPER_RADIUS;
CGPathAddArc(path, NULL,
p.x, p.y,
__PAN_UPPER_RADIUS,
3.0*M_PI/2.0,
4.0*M_PI/2.0,
false);
p.x += __PAN_UPPER_RADIUS;
//4
p.y += __PAN_UPPER_HEIGHT - __PAN_UPPER_RADIUS;
if (self.hintPosition == ACHintPositionFarRight ||
self.hintPosition == ACHintPositionRight) {
p.y += - 2*__PAN_UPPER_RADIUS + __PAN_CURVE_SIZE + __PAN_MIDDLE_HEIGHT;
} else { //ACHintPositionLeft & ACHintPositionFarLeft
p.y -= __PAN_CURVE_SIZE;
}
CGPathAddLineToPoint(path, NULL, p.x, p.y);
if (self.hintPosition == ACHintPositionFarRight ||
self.hintPosition == ACHintPositionRight) {
//5.1
p.x -= __PAN_UPPER_RADIUS;
CGPathAddArc(path, NULL,
p.x, p.y,
__PAN_UPPER_RADIUS,
4.0*M_PI/2.0,
1.0*M_PI/2.0,
false);
p.y += __PAN_UPPER_RADIUS;
//5.2
p.x -= self.hintAdditionalWidth + __PAN_UL_WIDTH-2*__PAN_UPPER_RADIUS;
CGPathAddLineToPoint(path, NULL, p.x, p.y);
//5.3
p.y += __PAN_UPPER_RADIUS;
CGPathAddArc(path, NULL,
p.x, p.y,
__PAN_UPPER_RADIUS,
3.0*M_PI/2.0,
2.0*M_PI/2.0,
true);
p.x -= __PAN_UPPER_RADIUS;
} else { //ACHintPositionLeft & ACHintPositionFarLeft
//5
p1 = CGPointMake(p.x, p.y + __PAN_CURVE_SIZE);
p.x -= __PAN_UL_WIDTH;
p.y += __PAN_MIDDLE_HEIGHT + __PAN_CURVE_SIZE*2;
p2 = CGPointMake(p.x, p.y - __PAN_CURVE_SIZE);
CGPathAddCurveToPoint(path, NULL,
p1.x, p1.y,
p2.x, p2.y,
p.x, p.y);
}
//6
p.y += __PAN_LOWER_HEIGHT - __PAN_CURVE_SIZE - __PAN_LOWER_RADIUS;
CGPathAddLineToPoint(path, NULL, p.x, p.y);
//7
p.x -= __PAN_LOWER_RADIUS;
CGPathAddArc(path, NULL,
p.x, p.y,
__PAN_LOWER_RADIUS,
4.0*M_PI/2.0,
1.0*M_PI/2.0,
false);
//8
p.x -= __PAN_LOWER_WIDTH;
p.y += __PAN_LOWER_RADIUS;
CGPathAddLineToPoint(path, NULL, p.x, p.y);
//9
p.y -= __PAN_LOWER_RADIUS;
CGPathAddArc(path, NULL,
p.x, p.y,
__PAN_LOWER_RADIUS,
1.0*M_PI/2.0,
2.0*M_PI/2.0,
false);
//10
p.x -= __PAN_LOWER_RADIUS;
p.y -= __PAN_LOWER_HEIGHT - __PAN_LOWER_RADIUS - __PAN_CURVE_SIZE;
CGPathAddLineToPoint(path, NULL, p.x, p.y);
if (self.hintPosition == ACHintPositionFarRight ||
self.hintPosition == ACHintPositionRight) {
//11
p1 = CGPointMake(p.x, p.y - __PAN_CURVE_SIZE);
p.x -= __PAN_UL_WIDTH;
p.y -= __PAN_MIDDLE_HEIGHT + __PAN_CURVE_SIZE*2;
p2 = CGPointMake(p.x, p.y + __PAN_CURVE_SIZE);
CGPathAddCurveToPoint(path, NULL,
p1.x, p1.y,
p2.x, p2.y,
p.x, p.y);
} else { //ACHintPositionLeft & ACHintPositionFarLeft
//11.1
p.x -= __PAN_UPPER_RADIUS;
CGPathAddArc(path, NULL,
p.x, p.y,
__PAN_UPPER_RADIUS,
4.0*M_PI/2.0,
3.0*M_PI/2.0,
true);
p.y -= __PAN_UPPER_RADIUS;
//11.2
p.x -= self.hintAdditionalWidth + __PAN_UL_WIDTH-2*__PAN_UPPER_RADIUS;
CGPathAddLineToPoint(path, NULL, p.x, p.y);
//11.3
p.y -= __PAN_UPPER_RADIUS;
CGPathAddArc(path, NULL,
p.x, p.y,
__PAN_UPPER_RADIUS,
1.0*M_PI/2.0,
2.0*M_PI/2.0,
false);
p.x -= __PAN_UPPER_RADIUS;
}
//12
p.y -= __PAN_UPPER_HEIGHT - __PAN_UPPER_RADIUS;
if (self.hintPosition == ACHintPositionFarRight ||
self.hintPosition == ACHintPositionRight) {
p.y += __PAN_CURVE_SIZE;
} else {
p.y -= - 2*__PAN_UPPER_RADIUS + __PAN_CURVE_SIZE + __PAN_MIDDLE_HEIGHT;
}
CGPathAddLineToPoint(path, NULL, p.x, p.y);
//13
p.x += __PAN_UPPER_RADIUS;
CGPathAddArc(path, NULL,
p.x, p.y,
__PAN_UPPER_RADIUS,
2.0*M_PI/2.0,
3.0*M_PI/2.0,
false);
//----
CGContextRef context;
UIGraphicsBeginImageContext(CGSizeMake(__WIDTH+self.hintAdditionalWidth,
__HEIGHT));
context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0.0, __HEIGHT);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextAddPath(context, path);
CGContextClip(context);
//----
CGRect frame = CGPathGetBoundingBox(path);
CGColorRef backColor = [UIColor whiteColor];
CGContextSetFillColorWithColor(context, backColor);
CGContextFillRect(context, frame);
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage * image = [UIImage imageWithCGImage:imageRef scale:[[UIScreen mainScreen] scale] orientation:UIImageOrientationDown];
CGImageRelease(imageRef);
UIGraphicsEndImageContext();
CFRelease(path);
return image;
}