Is there any way to provide this kind of effect in a UITextView
? If not, then how can I achieve this effect?
Asked
Active
Viewed 441 times
3

jscs
- 63,694
- 13
- 151
- 195

iOS Monster
- 2,099
- 1
- 22
- 49
-
2Drop Caps are weird in Core Text, you'd have to render an extra large letter with an additional CTFrameDraw call. – CodaFi Jul 02 '12 at 07:50
-
@CodaFi Hi, Thanx for your response. Can you please elaborate a bit or provide me any tutorial or anything for this? – iOS Monster Jul 02 '12 at 07:54
-
Unfortunately, no. CoreText is a beast of a framework. I can direct you to the [docs](https://developer.apple.com/library/mac/#documentation/StringsTextFonts/Conceptual/CoreText_Programming/Introduction/Introduction.html) though. – CodaFi Jul 02 '12 at 07:59
-
@CodaFi: No problem. Thanx for the guidance I'll look into it and try to find a solution. Thanx. – iOS Monster Jul 02 '12 at 08:01
1 Answers
1
Having the same requirement, I created a UIView
subclass that draws text with a drop cap. The text is drawn using core text, and as @CodaFi suggested the drop cap is drawn in a separate core text frame.
The full implementation of the class: https://gist.github.com/4596476
The meat of it looks something like this:
- (void)drawRect:(CGRect)rect {
// Create attributed strings
NSAttributedString *bodyText = [[NSAttributedString alloc] initWithString:[self.text substringWithRange:NSMakeRange(1, self.text.length -1)] attributes:_bodyAttributes];
NSAttributedString *capText = [[NSAttributedString alloc] initWithString:[[self.text substringWithRange:NSMakeRange(0, 1)] uppercaseString] attributes:_capAttributes];
CGRect capFrame = CGRectMake(0, 0, [capText size].width, [capText size].height);
// Set up graphics context
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// Create type frames
CGMutablePathRef bodyPath = CGPathCreateMutable();
CGAffineTransform transform = CGAffineTransformTranslate(CGAffineTransformMakeScale(1, -1), 0, -self.bounds.size.height);
CGPathMoveToPoint(bodyPath, &transform, CGRectGetMaxX(capFrame), 0);
CGPathAddLineToPoint(bodyPath, &transform, self.bounds.size.width, 0);
CGPathAddLineToPoint(bodyPath, &transform, self.bounds.size.width, self.bounds.size.height);
CGPathAddLineToPoint(bodyPath, &transform, 0, self.bounds.size.height);
CGPathAddLineToPoint(bodyPath, &transform, 0, CGRectGetMaxY(capFrame));
CGPathAddLineToPoint(bodyPath, &transform, CGRectGetMaxX(capFrame), CGRectGetMaxY(capFrame));
CGPathCloseSubpath(bodyPath);
CGMutablePathRef capPath = CGPathCreateMutable();
CGPathAddRect(capPath, &transform, CGRectMake(0, 0, capFrame.size.width+10, capFrame.size.height+10));
// Draw text
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) bodyText);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), bodyPath, NULL);
CFRelease(framesetter);
CTFrameDraw(frame, context);
CFRelease(frame);
framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)capText);
frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), capPath, NULL);
CFRelease(framesetter);
CTFrameDraw(frame, context);
CFRelease(frame);
}
The gist of it is you create two paths, one rectangle to contain the drop cap, and a rectangle with a notch removed for the rest of the text. The full implementation on gist allows you to control the fonts, spacing around the drop cap, and content inset of the whole view using properties.
It does not implement most of the features of a UITextView
(only the features I needed) so it may not be a full solution.
Hope that helps!

Anthony Mattox
- 7,048
- 6
- 43
- 59
-
Hi, thanks for your answer. This is a great effort you made. But I have already achieved this requirement of mine with HTML :). – iOS Monster Jan 23 '13 at 06:33
-
Yeah, it was an old question, but hopefully it will be useful to someone else! I initially used html as well, but webkit ended up being much too slow for my application. – Anthony Mattox Jan 25 '13 at 14:23