Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

arnieterm

macrumors regular
Original poster
Aug 28, 2008
201
0
Hi
Is it really not possible to show text of UIButton, UILabel etc as underlined in IPhone apps??
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
Apparently not. There doesn't seem to be any direct support for styled text. You can add UIImages to the buttons so you could add images that show the titles with underlining. You could also try to subclass UIButton, override drawRect to call the inherited method and then draw your underline. The UIButton class seems to report all kinds of properties related to where the content is drawn so you might be able to place the underline in the right place.

Why do you want underlined button titles?
 

arnieterm

macrumors regular
Original poster
Aug 28, 2008
201
0
A good suggestion.
I need underlined text in buttons that I show up as links [similar to web urls] but since I am not dealing with any web contents, these are just buttons with no visible borders, white background and blue colored text. That's why I am looking for underlined text.

Can you show a simple example of such subclassing?
Thanks
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
I haven't written any subclasses of UIButton but there's not much to that part. It's just like subclassing UIViewController. Just make a new file from the new file menu and choose Cocoa Touch Classes/UIView subclass. In the .h file change the base class to UIButton, like this:

Code:
@interface MyButton : UIButton
In the .m file you need to override drawRect like this:

Code:
- (void)drawRect:(CGRect)rect 
{
    // Drawing code
	[super drawRect:rect];
	
	// add code to draw lines here
}

You'll need to look at CoreGraphics to figure out how to draw a line.

Then to make a button one of your buttons either in code do it like this:

Code:
UIButton* button = [[MyButton alloc] initWithFrame:frame];

or in IB set the class kind to MyButton in the class inspector view.
 

arnieterm

macrumors regular
Original poster
Aug 28, 2008
201
0
I have created a subclass using UIButton with code as given below
Code:
@interface Button : UIButton
{

}

@implementation Button


- (void)drawRect:(CGRect)rect 
{
	
	CGContextRef context=UIGraphicsGetCurrentContext();		
			
	
	CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
	CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
	// Draw them with a 2.0 stroke width so they are a bit more visible.
	CGContextSetLineWidth(context, 1.0);
	
	// Draw a single line from left to right
	CGContextMoveToPoint(context,10, 22.0);
	CGContextAddLineToPoint(context, 100, 22.0);	
	CGContextStrokePath(context);
	// Drawing code	 
}
Though this code draws a line at the specified position
but i need to draw it exactly below the title. Also the line's length should be consistent with the title length
Any idea??
I am in dire need of underlined text in UIButton.
Thanks
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
In thinking about this further I think it might be simpler to generate an image that has the text underlined and use setImage:forState: on the button.

You would use the drawing code that you show but in addition draw the text into the context. This way you have more control over where exactly the text will go. You can figure out exactly how wide the text is and so on.

You'll need to generate two images, one for normal and one for hilighted, which will be the same except the colors will be different. You could try this with some simple images just to see if the button will do the right thing with your underlined text images.

I haven't done this myself.
 

arnieterm

macrumors regular
Original poster
Aug 28, 2008
201
0
hi PhoneyDeveloper
I cannot use an image containing line since there are a lot of buttons with varying title.
But I am successful in drawing a line using graphics in the custom button class. The only problem remains is that though I choose the starting co-ordinate for drawing text as Rect.size.width/4 and Rect.size.height/2. Here the drawn text appears slightly above the middle line of the button. It seeems to me that for a given font size do I also consider capHeight, xHeight, ascender, descender properties?
The problem now simply remains as for a given frame of button (x=10,y=20,width=30, height=30), you want to set text "Home" which should appear exactly in center similar to the case when you use setTitle method of UIButton

Thanks
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
I'm glad you're making progress. I'd like to see a screenshot.

Figuring out the algorithm that UIButton uses for deciding exactly where to place the text may be difficult. That's why I suggested that you draw the text in your code.

Most likely the button does use ascent, descent, and maybe leading to decide where to place the text. The simple method would be to center a rect of height (ascent + descent + leading), or maybe just (ascent + descent) since there's only one line, in the height of the button. That would be my first guess. It will certainly be close to that for the position of the baseline. Maybe, Rect.size.height/2 + descender. For the x coordinate you probably need to find out the length of the text and center that. Rect.size.width/2 - stringlength/2. Calculate stringlength with sizeWithFont:constrainedToSize:lineBreakMode.

You may wish to use the Pixie application to inspect the buttons in a magnified way while you're working on this in the simulator. Pixie is /Developer/Applications/Graphics Tools/Pixie.app.
 

arnieterm

macrumors regular
Original poster
Aug 28, 2008
201
0
For the given font, the sum of ascender and descender [absolute values] wil place the title in the desired position. See the attached image for visualization
 

Attachments

  • Picture 1.png
    Picture 1.png
    18.4 KB · Views: 6,738

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
The screenshot's a little small but I can see that the title is underlined. Great.

So is the baseline = ascent+descent relative to the bounds.y of the button?

One other thing: you might want the color of the underline to have some alpha value other than 1. That way the underline mixes more nicely with the text rather than simply overwriting it, especially if the underline RGB is different from the text foreground color.
 

AbelDu

macrumors newbie
Oct 26, 2008
1
0
The screenshot's a little small but I can see that the title is underlined. Great.

So is the baseline = ascent+descent relative to the bounds.y of the button?

One other thing: you might want the color of the underline to have some alpha value other than 1. That way the underline mixes more nicely with the text rather than simply overwriting it, especially if the underline RGB is different from the text foreground color.

I think someone should write a class that handles just that. It seems like doing it with a button has too much overhead for a simple link.

Ideas:

Class called Link

have the class take a display name and a URL string
have the class load the page when the link is pressed

should be pretty easy, if I have time I'll write it up and come up with an interface builder plugin so we all can use it.
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
I think someone should write a class that handles just that.

That would be nice.

Code:
It seems like doing it with a button has too much overhead for a simple link.

Don't know why you think that. Why do you think a button has a lot of overhead?

Ideas:

Class called Link

have the class take a display name and a URL string

A common use would have the link in the middle of other text that's not part of the link. Actually a UIWebView would do all this.

have the class load the page when the link is pressed

Actually a UIControl should post its action method when it's clicked, or activated. In fact since loading a page causes an app to be killed I don't think this is a great idea. Just have it post its action message. Or have this be a property of the control. It could open the page optionally. But I might prefer to open the page in a UIWebView in my app and not launch MobileSafari. The display and the action should be separate.
 

btknorr

macrumors newbie
Jan 5, 2009
1
0
I have created a subclass using UIButton with code as given below
Code:
@interface Button : UIButton
{

}

@implementation Button


- (void)drawRect:(CGRect)rect 
{
	
	CGContextRef context=UIGraphicsGetCurrentContext();		
			
	
	CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
	CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
	// Draw them with a 2.0 stroke width so they are a bit more visible.
	CGContextSetLineWidth(context, 1.0);
	
	// Draw a single line from left to right
	CGContextMoveToPoint(context,10, 22.0);
	CGContextAddLineToPoint(context, 100, 22.0);	
	CGContextStrokePath(context);
	// Drawing code	 
}
Though this code draws a line at the specified position
but i need to draw it exactly below the title. Also the line's length should be consistent with the title length
Any idea??
I am in dire need of underlined text in UIButton.
Thanks

I've done something similar when extending UILabel...here is how I got the correct positioning:

Code:
CGSize dynamicSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(99999, 99999) lineBreakMode:self.lineBreakMode];
CGContextMoveToPoint(context, 0, dynamicSize.height);
CGContextAddLineToPoint(context, dynamicSize.width, dynamicSize.height);
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
arnieterm, have you read through the iPhone Human Interface Guidelines document (MobileHIG.pdf)? Cuz what you appear to be proposing for your UI doesn't seem to jive with what Apple recommends.
 

mpramodjain

macrumors regular
Nov 20, 2008
152
0
Banglore
Custom UI

arnieterm, have you read through the iPhone Human Interface Guidelines document (MobileHIG.pdf)? Cuz what you appear to be proposing for your UI doesn't seem to jive with what Apple recommends.

What does this mean, Can't we have the Custom UI Done , as arnieterm was.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.