I want to add an outline or stroke to an editable UITextView
text as the user types. Exactly like memes : http://t.qkme.me/3oi5rs.jpg
I have to use a UITextView
since I need multi line support. I have tried all the approaches and reached the conclusion that I must use CoreText
. I got almost all of the solution working but got stuck at a point where the text in textview wraps. My drawRect
routine in the subview
of UITextView
correctly draws the outline text until the text wraps. Even when the text user inputs is wrapped, the outline text that I draw does not. Here's my implementation of the drawRect
method : https://gist.github.com/4498988. On line 29, I am using char wrapping :
CTLineBreakMode linebreakmode = kCTLineBreakByCharWrapping;
I have already tried the wordwrapping option (which is also the default) to no use.
My question is :
How do I get the text that I draw to wrap correctly so it appears as an outline to the typed text?
// make your UITextView as a subclass of UITextView
// and override -drawRect: method in your UITextView subclass
- (void)drawRect:(CGRect)rect
{
self.textColor = [UIColor clearColor];
[self setTypingAttributes:[NSDictionary dictionaryWithObjectsAndKeys:self.font, NSFontAttributeName, _textBaseColor, NSForegroundColorAttributeName, nil ]]; // _textBaseColor is any color of your choice
CGRect newRect = CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextDrawingMode(context, kCGTextStroke);
// Make the thickness of the outline shadow. and increase the y position of shadow rect by 2.
CGContextSetLineWidth(context, (TEXTOUTLINE_PERCENT/100 * self.font.pointSize)+1); // TEXTOUTLINE_PERCENT can be 25.
CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetLineCap(context, kCGLineCapButt);
CGContextSetStrokeColorWithColor(context, [UIColor clearColor].CGColor);
CGRect shadowrect = newRect;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
shadowrect.origin.y += 0.5;
}
else
{
shadowrect.origin.y += 2;
}
[self.text drawInRect:shadowrect withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:self.font, NSFontAttributeName, SHADOW_COLOR , NSForegroundColorAttributeName, nil]]; // SHADOW_COLOR can be [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.3]
// Make the thickness of the outline border of the text.
CGContextSetLineWidth(context, TEXTOUTLINE_PERCENT/100 * self.font.pointSize); // TEXTOUTLINE_PERCENT can be 25.
CGContextSetStrokeColorWithColor(context, [[UIColor clearColor] CGColor]);
[self.text drawInRect:newRect withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:self.font, NSFontAttributeName, self.textOutlineColor , NSForegroundColorAttributeName, nil]];
// Draw filled text. This is the actual text.
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
[self.text drawInRect:newRect withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:self.font, NSFontAttributeName, _textBaseColor, NSForegroundColorAttributeName,_textBaseColor, NSStrokeColorAttributeName, nil]];
[super drawRect:rect];
}
Just make a string with CSS
NSString *htmlstring = [[NSString alloc] initWithFormat:@"<html><font style=\"text-shadow: 0 0 0.2em #F87, 0 0 0.2em #F87\">%@</font></html>", YourTextView.text, nil];
^That will make whatever text is in the TextView glow read on a webpage.
(You can also give it a black background if you'd like... use this:
NSString *htmlstring = [[NSString alloc] initWithFormat:@"<html><body bgcolor=\"#000000\"><font style=\"text-shadow: 0 0 0.2em #F87, 0 0 0.2em #F87\">%@</font></body></html>", YourTextView.text, nil];
Now save it as an html file and load it into a UIWebView. Or inject it into a URL via javascript and load that URL into a UIWebView.
Set the UIWebView frame and location to match that of your UITextView so that it will go ontop of it and the red-glowing text with the black background will be displayed.
Make an HTML file that has red glowing text in an editable textfield (TextArea).
Set the background of all elements to be transparent.
Make it into a string and load it into a UIWebView that is ontop of the image you want to put the text on.
Load the HTML string into the UIWebView and also make the UIWebView itself transparent.
*Also you might need to make your UIWebView a property and synthesize it.
Here's the code (without the synthesizing and property)
.h:
@interface ViewController : UIViewController <uiwebviewdelegate></uiwebviewdelegate> {
IBOutlet UIWebView *webView;
//... other objects you already have can go here too..
}
.m:
self.webView.delegate = self;
NSString *htmlstring = [[NSString alloc] initWithFormat:@"<html><body style='background-color: transparent;'><textarea name='myTextArea'cols='20' rows='10' style='text-shadow: 0 0 0.2em #F87, 0 0 0.2em #F87; background-color:transparent; border:none'>You Can Edit This Text.</textarea></body></html>"];
[self.webView loadHTMLString:htmlstring baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
self.webView.opaque = NO;
self.webView.backgroundColor = [UIColor clearColor];
Edit: Here is the code for the property and synthesize of the "webView"
@property(nonatomic,retain)IBOutlet UIWebView *nubrowser; //put in .h file at end of "@Interface" function after the closing curly bracket ("}")
@synthesize webView; //put in .m file directly after "@implementation" function