iPhone : Underline Text - iphone

Is there appeared easy way to underline text in iOS 4 ?? In IB maybe ? Thanks in advance...

As far as I know you cannot underline text.
You can "fake" it though by (for example) placing an UImageView or a regular View just underneath with the same color as your text. You can use strike-through etc, but cannot underline.
Edit:
You could use this approach to underline your UILabel though. You could namely use a custom UILabel. So you could create some class like CUILabel that inherits UILabel and replace its drawRect method in the #implementation section with the following:
- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(ctx, 0.0f/255.0f, 0.0f/255.0f, 255.0f/255.0f, 1.0f); // Your underline color
CGContextSetLineWidth(ctx, 1.0f);
UIFont *font = [UIFont systemFontOfSize:16.0f];
CGSize constraintSize = CGSizeMake(MAXFLOAT, MAXFLOAT);
CGSize labelSize;
labelSize = [self.text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
CGContextMoveToPoint(ctx, 0, self.bounds.size.height - 1);
CGContextAddLineToPoint(ctx, labelSize.width + 10, self.bounds.size.height - 1);
CGContextStrokePath(ctx);
[super drawRect:rect];
}

Just subclass UILabel and in drawRect after you draw your text just draw an simple line under the text. Take a look at StrikeUILabel it have some bugs in it but you can start from that class.

NSMutableAttributedString/NSAttributedString allows you to create text with various rich attributes like font,color,type styles (including underline). For generic details follow this link..
Introduction to Attributed String Programming Guide
Specific to underline of text, this link may help..
Changing an Attributed String

Sometimes i prefer to use UILabel as Underline with background of Underline color, no text, height 1 or 2 pixel and width as equal to Text to be underline...

Related

respond to selector method for unsupported implementations

In my app I need to display under line text in a label so I used following code to display underlined text
NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:normalString];
[attributeString addAttribute:NSUnderlineStyleAttributeName
value:[NSNumber numberWithInt:1]
range:(NSRange){0,[attributeString length]}];
wesiteAddressLabel.attributedText = attributeString;
This method and some other implementations which works fine in iOS 6.1
But when I executed in iOS 5.1 and below, app gets crashed due to the reason,
[attributeString addAttribute:NSUnderlineStyleAttributeName
value:[NSNumber numberWithInt:1]
range:(NSRange){0,[attributeString length]}];
not supported in previous versions
So I want to use respondsToSelector: method to check if instance responds and implement another method for unsupported selector.
How I use this method?
As from the documentation:
attributedText The styled text displayed by the label.
#property(nonatomic,copy) NSAttributedString *attributedText
Discussion This property is nil by default. Assigning a new value to
this property also replaces the value of the text property with the
same string data, albeit without any formatting information. In
addition, assigning a new a value updates the values in the font,
textColor, and other style-related properties so that they reflect the
style information starting at location 0 in the attributed string.
Availability Available in iOS 6.0 and later. Declared In UILabel.h
You should check if the a specific UIView element is able to respond to the attributedText. In this case:
[wesiteAddressLabel respondsToSelector:#selector(attributedText)];
Should be enough
For previoes versions you have to draw an UIImageView Just below the Text by getting the with and Height of text in each line.
Or you can create a category of label by using DrawRect method.
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(ctx, 0.0f/255.0f, 0.0f/255.0f, 255.0f/255.0f, 1.0f); // Your underline color
CGContextSetLineWidth(ctx, 1.0f);
UIFont *font = [UIFont systemFontOfSize:16.0f];
CGSize constraintSize = CGSizeMake(MAXFLOAT, MAXFLOAT);
CGSize labelSize;
labelSize = [self.text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
CGContextMoveToPoint(ctx, 0, self.bounds.size.height - 1);
CGContextAddLineToPoint(ctx, labelSize.width + 10, self.bounds.size.height - 1);
CGContextStrokePath(ctx);
[super drawRect:rect];
}

How to draw underline to a multiline label without using CoreText?

I have been trying to underline a multiline label but I am not able to do that.
I have referred to this link but this doesn't seem to help me.
How can be done without using NSAttributedString and coreText?
You could use some of these open source projects from GitHub which are like UILabel's but support an attributed string:
TTTAttributedLabel or OHAttributedLabel
Following steps can be helpful.
Extend UILable OR UIView.
Implement - (void)drawRect:(CGRect)rect
In that method get context using `CGContextRef ctx = UIGraphicsGetCurrentContext();
Set text you want to set using this.
CGContextSetRGBFillColor(context,1.0, 0.0, 0.0, 1.0);
CGContextSetTextMatrix(context,CGAffineTransformMakeTranslation(0,pageSize.height));
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSelectFont(context, "Helvetica", 30, kCGEncodingMacRoman);
char *str=(char*)[#"TEXT" UTF8String];
CGContextShowTextAtPoint(context,476/2-200,673/2+100,str,strlen(str));
Set Line using this code.
CGContextSetLineWidth(ctx, 3);
Draw line using this code.
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, thisX, thisY);
CGContextAddLineToPoint(ctx, thatX,thatY);
CGContextStrokePath(ctx);
Hope above collected segments of code helps you....

How to underline UILabel in iPhone SDK? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
underline text in UIlabel
Can any one provide a code to show me how to underline text in UILabel? In Interface Builder I underline the UILabel text but it's not working.
You can inheritate UILabel and draw a line yourself in drawTextInRec
you need to implement the drawRect: method of your UIView inherited class.
- (void)drawRect:(CGRect)rect
{
// Get the Render Context
CGContextRef ctx = UIGraphicsGetCurrentContext();
// Measure the font size, so the line fits the text.
// Could be that "titleLabel" is something else in other classes like UILable, dont know.
// So make sure you fix it here if you are enhancing UILabel or something else..
CGSize fontSize =[self.titleLabel.text sizeWithFont:self.titleLabel.font
forWidth:self.bounds.size.width
lineBreakMode:UILineBreakModeTailTruncation];
// Get the fonts color.
const float * colors = CGColorGetComponents(self.titleLabel.textColor.CGColor);
// Sets the color to draw the line
CGContextSetRGBStrokeColor(ctx, colors[0], colors[1], colors[2], 1.0f); // Format : RGBA
// Line Width : make thinner or bigger if you want
CGContextSetLineWidth(ctx, 1.0f);
// Calculate the starting point (left) and target (right)
float fontLeft = self.titleLabel.center.x - fontSize.width/2.0;
float fontRight = self.titleLabel.center.x + fontSize.width/2.0;
// Add Move Command to point the draw cursor to the starting point
CGContextMoveToPoint(ctx, fontLeft, self.bounds.size.height - 1);
// Add Command to draw a Line
CGContextAddLineToPoint(ctx, fontRight, self.bounds.size.height - 1);
// Actually draw the line.
CGContextStrokePath(ctx);
// should be nothing, but who knows...
[super drawRect:rect];
}
Taken form iPhone Programming how to underline UILabel
You could also inherit UILabel . See the belwo SO post, which does exactly the same.
Underline text in UIlabel

Draw background color in a UILabel rect only where my text is

I need to create a custom UILabel to display some dynamic multiline text. The text color is white on a black background. But the background should only be visible right behind the text to simulate the effect of an selected text area.
I started with subclassing UILabel and overriding drawTextInRect to do my own drawings.
- (void) drawTextInRect:(CGRect)rect
{
/* do some custom drawings here */
[super drawTextInRect:rect];
}
So far i could not figure out a way to compute the text-bounds do draw my background into.
Does anybody now how do do this kind of stuff? Thanks a lot.
NSString has some additions in UIKit to allow for calculating the size used to render the string, given various parameters. You can use these methods to calculate the size the UILabel needs to render the string, and then resize the UILabel to precisely this size. Look in the documentation for a method called -sizeWithFont:, all of the other variations are listed there. Make sure you use the right method to match how your UILabel is configured.
There is one caveat here, which is that on iOS 4, there is a bug where these methods actually return a slightly different size than is actually used for drawing (at least for the system font on iPhone 4's [e.g. Helvetica Neue], I don't know if this bug affects any other fonts). Unfortunately the only workaround I know of is to switch to Core Text for all your text rendering, so you may just prefer to live with this bug (if it even affects you) until Apple pushes out a software update. This bug does affect Apple's own applications so there is plenty of precedent for not handling it.
Ok. Now after some input from stackoverflow i am using this code snippet to get the textbounds but it only works fine with single line text.
- (void) drawTextInRect:(CGRect)rect
{
CGFloat lineHeight = [self.text sizeWithFont:self.font].height;
CGSize testSize = CGSizeMake(320, lineHeight * self.numberOfLines);
CGSize textSize = [self.text sizeWithFont:self.font constrainedToSize:testSize lineBreakMode:self.lineBreakMode];
//NSLog(#"drawTextInRect lineHeight %f, width %f x height %f", lineHeight, textSize.width, textSize.height);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
CGContextAddRect(context, CGRectMake(0, 0, textSize.width, textSize.height));
CGContextFillPath(context);
CGContextRestoreGState(context);
[super drawTextInRect:rect];
}
If i have multiline text i still need some code to compute the path-information of the text and not just the bounding rect so that i can use CGContextDrawPath to draw my background. Any thoughts on that? Thanks.

Drop Shadow on UITextField text

Is it possible to add a shadow to the text in a UITextField?
As of 3.2, you can use the CALayer shadow properties.
_textField.layer.shadowOpacity = 1.0;
_textField.layer.shadowRadius = 0.0;
_textField.layer.shadowColor = [UIColor blackColor].CGColor;
_textField.layer.shadowOffset = CGSizeMake(0.0, -1.0);
I have a slightly different problem - I want a blurred shadow on a UILabel. Luckily, the solution to this turned out to be number (2) from Tyler
Here's my code :
- (void) drawTextInRect:(CGRect)rect {
CGSize myShadowOffset = CGSizeMake(4, -4);
CGFloat myColorValues[] = {0, 0, 0, .8};
CGContextRef myContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(myContext);
CGColorSpaceRef myColorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef myColor = CGColorCreate(myColorSpace, myColorValues);
CGContextSetShadowWithColor (myContext, myShadowOffset, 5, myColor);
[super drawTextInRect:rect];
CGColorRelease(myColor);
CGColorSpaceRelease(myColorSpace);
CGContextRestoreGState(myContext);
}
This is in a class that extends from UILabel and draws the text with a shadow down and to the right 4px, the shadow is grey at 80% opacity and is sightly blurred.
I think that Tyler's solution number 2 is a little better for performance than Tyler's number 1 - you're only dealing with one UILabel in the view and, assuming that you're not redrawing every frame, it's not a hit in rendering performance over a normal UILabel.
PS This code borrowed heavily from the Quartz 2D documentation
I don't think you get built-in support for text shadows here, the way you do with UILabel.
Two ideas:
(1) [Moderately tricky to code.] Add a second UITextField behind the original, at a very small offset (maybe by (0.2,0.8)? ). You can listen to every text change key-by-key by implementing the textField:shouldChangeCharactersInRange:replacementString: method in the UITextFieldDelegate protocol. Using that, you can update the lower text simultaneously. You could also make the lower text (the shadow text) gray, and even slightly blurry using the fact that fractionally-offset text rects appear blurry. Added: Oh yea, don't forget to set the top text field's background color to [UIColor clearColor] if you go with this idea.
(2) [Even more fun to code.] Subclass UITextField and override the drawRect: method. I haven't done this before, so I'll mention up front that this depends on this being the designated drawing method, and it may turn out that you have to override another drawing function, such as drawTextInRect:, which is specific to UITextField. Now set up the drawing context to draw shadows via the CGContextSetShadow functions, and call [super drawRect:rect];. Hopefully that works -- in case the original UITextField code clears the drawing context's shadow parameters, that idea is hosed, and you'll have to write the whole drawing code yourself, which I anti-recommend because of all the extras that come with UITextFields like copy-and-paste and kanji input in Japanese.
Although the method of applying the shadow directly to the UITextView will work, it's the wrong way to do this. By adding the shadow directly with a clear background color, all subviews will get the shadow, even the cursor.
The approach that should be used is with NSAttributedString.
NSMutableAttributedString* attString = [[NSMutableAttributedString alloc] initWithString:textView.text];
NSRange range = NSMakeRange(0, [attString length]);
[attString addAttribute:NSFontAttributeName value:textView.font range:range];
[attString addAttribute:NSForegroundColorAttributeName value:textView.textColor range:range];
NSShadow* shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor whiteColor];
shadow.shadowOffset = CGSizeMake(0.0f, 1.0f);
[attString addAttribute:NSShadowAttributeName value:shadow range:range];
textView.attributedText = attString;
However textView.attributedText is for iOS6. If you must support lower versions, you could use the following approach. (Dont forget to add #import <QuartzCore/QuartzCore.h>)
CALayer *textLayer = (CALayer *)[textView.layer.sublayers objectAtIndex:0];
textLayer.shadowColor = [UIColor whiteColor].CGColor;
textLayer.shadowOffset = CGSizeMake(0.0f, 1.0f);
textLayer.shadowOpacity = 1.0f;
textLayer.shadowRadius = 0.0f;