how to set the bold in part of the text in UILabel - iphone

I am new in iPhone application development. How to set the bold in part of the text in UILabel.
Example:
Step 1- Separate all parts of the plant (stem, roots, leaves, flower etc..)
Step 2- Only test one part at a time
I need like example in UILabel
Thanks in advance

Implement TTTAttributedLabel or OHAttributedLabel and use:
NSMutableAttributedString *theText = theLabel.text;
[theText applyFontTraits:NSBoldFontMask range:NSMakeRange(0,[text length])];
theLabel.text = theText;
to bold specific parts of the string (change the NSRange as required).

For now, you're going to have to use a third party component, since there's no attributed string support in UILabel.
Try https://github.com/mattt/TTTAttributedLabel/
In order of increasing complexity, here's some other solutions:
Alternatively, use a WebView with HTML.
Alternatively, use a CATextLayer, this is only slightly more work than adding a UILabel, but you need a little understanding of how layers work vs. views.
Alternatively, draw your strings yourself using CoreText.

Related

Objective c - Text indentation

This question is about implementing text indentation ("The placement of text farther to the right to separate it from surrounding text") in iOS.
Take for example the following text:
This is the first section.
This is the second one,
with two lines.
This is the third.
Notice that the second row in section 2 begin farther to the right and just below the line above.
My code contains an array of NSString, each one should be display as a section with numeric bullet like above. for example:
NSArray *array = [NSArray arrayWithObjects:#"1. This is the first section.", #"2. This is the second one, with two lines.", #"3. This is the third.", nil];
I use UILable to display the text on screen.
To set the text from the array to the label, and to separate each string in a new line I use
myLabel.text = [array componentsJoinedByString:#"\n"];
Any ideas how to get this effect?
This is possible to some degree in iOS6 with - [UILabel setAttributedText:].
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.headIndent = 29;
myLabel.attributedText = [[NSAttributedString alloc] initWithString:
#"1.\tShort line.\n2.\tLong line with content that triggers wrapping.\n3.\tShort line."
attributes:#{NSParagraphStyleAttributeName: paragraphStyle}];
This adds indentation to the subsequent lines. It looks like iOS doesn't support tab stops in the same way as OSX so I'm not seeing a way to adjust the gap between the number and the text. This is probably possible in CoreText.
Of course, you could also just replace the label with a UIWebView and have full formatting control on all versions of iOS at the cost of performance.
Well I decided to implement it my self without using Core Text, I just created a view strcture that make all the indentation work by itself, and let you customize it as you want.
For all of you interested in the implementation, you can see the source code and an example project here:
ECListView Project
UILabel is not going to cut it if you have any kind of specific layout requirements. For that, you're going to need to dig into Core Text. The good news is that Core Text will let you do any kind of text layout you can imagine. The bad news is that all that power brings with it some complexity, so to use it you're going to have to invest some time learning how the framework works.
An alternative that's suitable in some situations is to use a web view to display your text. UIWebView will let you do whatever text layout you can manage using HTML and CSS.

Overriding Emoji Graphics

I want to override the emoji icons with my own custom graphics (only within my app).
From what I've read so far, one possible solution is to create a custom font extension which overrides the desired unicode characters. Preferable I would like to maintain inter-operability with CATextLayer.
Edit: Looks like custom fonts won't be my solution; fonts must be defined in gray-scale. Next possibility: Creating a custom CALayer, chunking the string into segments based on emoji code, and doing the type setting + graphics rendering manually (i.e. with core graphics and core text)
Edit: Also looking to maintain smooth scrolling performance in a table views.
I have devoted a lot of time trying to do the same. Your best bet is to replace the unicode values for the emoji in your NSString eg. \uE100 etc. with a placeholder string. You could replace the emoji encodings with an HTML Tag and use either UIWenViews or DTCoreText to draw the image inline.
I have done this, it works too, but it will be a little slow (Specially if you want to display this Label in table views.)
Here is a little starter:
Make a dictionary with UIImages as objects and placeholder strings as keys:
self.emoticonDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"happyEmoticon.png", #":)",
#"sadEmoticon.png", #":(",
#"testImg.png", #"\uE100",
nil];
__block NSString *text1 = [NSString stringWithFormat:#"<html><p>%#</p></html>",text];
[self.emoticonDict enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) {
text1 = [text1 stringByReplacingOccurrencesOfString:key withString:[NSString stringWithFormat:#"<img height= 15 width= 15 src=\"%#\">",obj]];
}];
You can at this point load this HTML into a UIWebView and you will have what you want.
[myWebView loadData:_htmlData MIMEType:#"text/html" textEncodingName:#"utf-8" baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];//do create the webview first
If the slow speed of a UIWebView is a concern, you can read ahead. In either case do look at the note towards the end of this answer.
To create a DTAttributedLabel, we do the following:
First we build a NSattributedString using the DTHTMLAttributedStringBuilder:
NSAttributedString *temp = [[[DTHTMLAttributedStringBuilder alloc] initWithHTML:text1
options:#{
DTDefaultFontFamily: #"Helvetica",
DTDefaultFontSize:#15,};
documentAttributes:nil]
generatedAttributedString];
Then you can use a DTAttributedLabel instance to display temp.
self.tempLabel.attributedString = temp;//create a DTAttributedLabel Instance called tempLabel before this, I had it as a property
My objective was to generate text label's really fast (Table Views) while supporting custom emoticons. DTAttributedLabels are fast (much faster than a UIWebView)
NOTE:
I also made a custom font where I had mapped the unicode values for the emojis to a custom glyph. To my surprise, still the default emojis were displayed. I would like to claim here that whenever iOS (CoreText) comes across a character whose value lies in the Emoji section, it draws it using the AppleColorEmoji font by default. The lack of documentation on how Apple Color Emoji font is actually drawn on iOS actually makes it difficult for me to prove this, but this seems to be a plausible explanation.
If you drop an emoji from the character palette app onto a file in textEdit, then select it and try to change the font, you see that it doesn't happen.
Similarly, if you type some text, then select it and try to change it's font to Apple Color Emoji, you'll see it doesn't happen. When I decompiled the Apple Color Emoji font, I didn't find character mappings or glyphs for textual characters (except 0-9). Somehow, even if you set a label's font as Apple Color Emoji, the font for the textual (non-emoji) part of your label's text is set to something else.
Kindly feel free to comment and share your knowledge since this region around the Apple Color Emoji font still remains very unclear.
One solution would be to use the UITextField or TextView delegate and listen to the user's input. When they type an emoji character, pop in a UIImageView inline with the text, and delete the emoji icon with the input.
There's a few mentions of this issue on Apple's private devforums (which you have access to if you're a registered member of the iOS developer program).
It sounds like the potential solution would be to explicitly set the font for whatever you're trying to display.

CoreText and strikethrough on iPhone

I'm currently struggling with the need to display strikethrough text in many UITableViewCells. Something that written in HTML would looke like
<strike>€99</strike> save 50% => now €49
I don't want to use a UIWebView just for a single line of text, especially that it's used in small UITableViewCells. I know there are reusable cells and all, but I'd like to keep things the more memory-efficient way possible.
So... I'm using NSAttributedStrings, with the help of AliSoftware's UILabel-replacement OHAttributedLabel. The fact that it's only available starting with iOS 4.0 is no problem, as we use all kinds of stuff only 4.0-compatible.
I can manage to create the attributed string, it displays text in the OHAttributedLabel, OK, that's cool. But what I can't achieve is setting the "strikeout", or "strikethrough" attribute.
Basically I go like this:
NSString *price = [NSString stringWithFormat:#"%01.2f €", product.price];
NSString *rate = [NSString stringWithFormat:#" -%01.0f%%", product.reductionRate];
NSMutableAttributedString *s = [NSMutableAttributedString attributedStringWithString:price];
[s addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlinePatternSolid | NSUnderlineStyleSingle] range:NSRangeFromString(price)];
[attributedLabel setAttributedText:s];
But here, the three NS* constants are undefined. I've imported CoreText.h, Foundation/NSAttributedString.h, to no avail. I've seen somewhere on the web that
NSStrikethroughStyleAttributeName = #"NSStrikethroughStyleAttributeName", and that NSUnderlinePatternSolid = 0 and NSUnderlineStyleSingle = 1, but hard-coding these values don't give anything.
One thing I got with auto-completion are the equivalent kCT...* constants, but there are kCTUnderlineStyleAttributeName, kCTStrokeWidthAttributeName, ... but no mention of kCTStrikethrough_anything.
What should I do to display that *$|#!# piece of strike-through text ?
With iOS 6 you can use NSStrikethroughStyleAttributeName
[attributedString addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInt:NSUnderlineStyleSingle] range:selectedRange];
While it may seem out of place, the numberWithInt value is correct as NSUnderlineStyleSingle.
A simpler approach might be two labels, using the answer to this question - Pixel Width of the text in a UILabel - to strikeout the text in one of the labels.

One label, two different fonts?

I need to format text in a label like this:
username: some text from this user. This will
create additional lines of text that will go
on and on and on.
Where "username" is bold. This will go into a UILabel, which is in a custom table cell. Is there a way to get this type of layout?
For this relatively simple case, you might be able to fake it. Have one label with the bold username, and another label with the plain text in the same position. Insert enough spaces before the plain text to leave room for the username. You can use UIStringDrawing methods to measure the bold text and the spaces.
CGSize usernameSize = [theUsername sizeWithFont:theBoldUsernameFont];
CGSize spaceSize = [#" " sizeWithFont:thePlainCommentFont];
NSString *indentedComment = [NSString stringWithFormat:#"%*s%#" , (int)ceil( usernameSize.width / spaceSize.width ) , "" , theComment];
If you use plain UILabel it's not available. Use two labels for this task.
You need to use either a UIWebView or CoreText to do this kind of advanced text layout. A web view has a lot of overhead but is most flexible and you can't use it effectively in a UITableView cell. CoreText is low level and not that well documented. You could ditch the table view and just lay out the table with CSS and HTML in the web view, which is how I do it.
You can still use a UITableViewCell but have the cell use a UIWebView subview. Set up a custom cell subclass with a clever setter method that allows you to send nsstrings to the method with turns those into a pretty formatted view.

How to get the same UITableViewCell layout as in the Address Book app?

I currently have a custom UITableViewCell which contains a few labels, and an image.
The "main" label is used to display people's names. Currently, I'm styling it in bold text.
What I'd like to do (to gain some space and readability), is to mimic the Address Book app cell style, that is: first name in light text, and family name in bold text.
Is there a way to do this using the same UILabel? Or, should I use 2 different UILabels? How should I layout them, without knowing their sizes?
Thanks in advance for your assistance!
See this sample code from atebits:
http://atebits.cachefly.net/blog/FastScrolling/FastScrolling.zip
It does something similar to what you want.
You can use the built-in UITableViewCellStyleValue2. From the UITableViewCell.h header file:
UITableViewCellStyleValue2, // Right aligned label on left with blue
//text and left aligned label on right (Used in Phone/Contacts)
Pass this into your [[UITableViewCell alloc] initWithStyle:...] method.
I think it's table view cell with UITableViewCellStyleDefault style. If you'd like to use different font attributes then you need to use different labels (because there is no attributed strings yet). To calculate size of these labels you should use following method:
- (CGSize)sizeWithFont:(UIFont *)font minFontSize:(CGFloat)minFontSize actualFontSize:(CGFloat *)actualFontSize forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode;
or any relevant from NSString(UIStringDrawing).
Also, you can use custom strings drawing instead of UILabel.