"NSAttributedString initWithData: options: documentAttribute: error:" not working as expected - ios

I'm trying to fill a UITableView with HTML strings. Getting the strings, putting them into cell etc. everything is ok. And I want to change my NSAttributedText's font and font size. I wrote the code below.
I checked the code via the first NSLog, if my UIFont is in the dictionary as expected; so it is in the dictionary. still no problem. but my font and font size is not changing on runtime. There is no console error. Just not working.
Second NSLog is for checking the attributedString's font and size. It says, my string is "Times New Roman" with fontSize:12. But as you will see in the code, I'm trying to make it "Verdana" with Size 15
Can anyone help me about this? Thanks.
PS: I'm keeping the strings in some objects. obj.name is the string which I want to write into table cell.
Html strings have some unwanted tags, so the function [self clearTheHtml:obj.name] function is clearing them.
NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
UIFont *font = [UIFont fontWithName:#"Verdana" size:15];
[attributes setObject:font forKey:NSFontAttributeName];
NSString *s = [self clearTheHtml:obj.name];
NSLog(#"%#", [attributes objectForKey:NSFontAttributeName]); //to see if my font is not in the dictionary.
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithData:[s dataUsingEncoding:NSUnicodeStringEncoding] options:#{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:&attributes error:nil];
NSLog(#"%#", attributedString);
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2 forIndexPath:indexPath];
cell.textLabel.attributedText = attributedString;
EDIT:
here is the NSString *s :
2014-01-25 07:38:04.527 KadirB[7483:70b]
''Narakas 2013 Brachial Plexus Surgery Symposıum'' 23-25 Mayıs 2013 tarihleri arasında Montreux, İsviçre de yapıldı. Brakial Plexus sorunlarına yönelik son gelişmeler toplantıda tartışıldı.

I've had the same problem just a couple of days ago. I solved by simply changing the implementation like so:
...
NSMutableAttributedString *attributedString = ...;
[attributedString addAttributes:#{NSFontAttributeName: font} range:NSMakeRange(0, attributedString.length)];
I hope it helps you as well.

Related

NSMutableAttributedString doesn't show string in different color for some specific range in iOS 8 & iOS 9

I am using attributes string in my code. To set font & color of text for some specific range.
For this I am using below code.
Font is working for range but color is not set for that range. There may be some issue in NSForegroundColorAttributeName.
Please let me know if anyone have solution.
NSDictionary *attrs = #{ NSFontAttributeName:[UIFont systemFontOfSize:12.0f],NSForegroundColorAttributeName : [UIColor redColor] };
NSMutableAttributedString *titleStr = [[NSMutableAttributedString alloc]initWithString:#"New Message from Test"];
[titleStr addAttributes:attrs range:NSMakeRange(0, 3)];
I also faced the similar problem. So I passed my string as HTML string and got it done like this.
NSString *name = #"<center><font color='#cd1c5f' size='4px'>"
#"New"
#"</font>"
#"<font color='#000000' size='4px'>"
#"Message from test"
#"</font></center>";
NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[name dataUsingEncoding:NSUnicodeStringEncoding] options:#{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
_lbl_nm.attributedText=attrStr;
You can append two attribute string with different attributes of red colour & text colour. Lets try using the following code chunk.
NSDictionary *attrs = #{NSForegroundColorAttributeName:[UIColor redColor], NSFontAttributeName:[UIFont systemFontOfSize:12.0]};
NSMutableAttributedString *titleString = [[[NSMutableAttributedString alloc] initWithString:#"New" attributes:attrDict] autorelease];
attrs = #{NSForegroundColorAttributeName:[UIColor lightTextColor], NSFontAttributeName:[UIFont systemFontOfSize:12.0]};
NSAttributedString *messageString = [[[NSAttributedString alloc] initWithString:#" Message from Test" attributes:attrs] autorelease];
[titleString appendAttributedString:messageString];
[self.titleTextView setAttributedText:titleString];
Check if you are changing the textcolor of the label after you set the attributed title. Thats the only way you will face this problem. Do it before you set the title.
cell.textLabel.textColor = [UIColor grayColor];
cell.textLabel.attributedText = titleStr;
I don't see any problems with your code. I just copied your code and tested, everything's fine.

NSDocumentTypeDocumentAttribute doesn't work with NSFontAttributeName

Story
App receives strings with html tags that were edited in CMS. App receives that strings and put to UILabel. Not so long ago html tags were added to this strings. Obviously strings with html tags looks fine in site.
I made an investigation and found that we can use attributed strings for UILabel.
//attributes dictionary
NSDictionary *attrs =
#{
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
};
NSAttributedString* attrString = [[NSAttributedString alloc] initWithData:[textString dataUsingEncoding:NSUnicodeStringEncoding]
options:attrs
documentAttributes:nil
error:nil];
Ok, now tags are enabled. But I lost my font, text looks like... default html text! That strings take their font's from css, but I receive bare strings with html tags. Just add NSFontAttributeName: [UIFont systemFontOfSize:10.f] to attrs dictionary. But without any success.
I made second try with NSMutableAttributedString:
//attributes dictionary
NSDictionary *attrs =
#{
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
};
NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithData:[textString dataUsingEncoding:NSUnicodeStringEncoding]
options:attrs
documentAttributes:nil
error:nil];
//and set font later
[attrString setAttributes:#{NSFontAttributeName:font} range:NSMakeRange(0, attrString.length)];
And now I've got label without any html tags, but this last step overrides all changes(bold, italic, etc.) from tags.
Question
How can we use html tags in attributed strings but set our font for them?
I am also looking for solution of this issue.
So far I Solved this by using the following code. Here I know HTML always contains Times new roman font. But If anybody find any dynamic solution please provide happily.
NSRange range = NSMakeRange(0, [parsedAttributedString length]);
[parsedAttributedString enumerateAttribute:NSFontAttributeName inRange:range options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id value, NSRange range, BOOL *stop)
{
UIFont* currentFont = value;
UIFont *replacementFont = nil;
if ([currentFont.fontName rangeOfString:#"BoldMT" options:NSLiteralSearch].location != NSNotFound)
{
replacementFont = [UIFont fontWithName:#"HelveticaNeue-Bold" size:14.0f];
}
else if ([currentFont.fontName rangeOfString:#"BoldItalicMT" options:NSLiteralSearch].location != NSNotFound)
{
replacementFont = [UIFont fontWithName:#"HelveticaNeue-BoldItalic" size:14.0f];
}
else if ([currentFont.fontName rangeOfString:#"ItalicMT" options:NSLiteralSearch].location != NSNotFound)
{
replacementFont = [UIFont fontWithName:#"HelveticaNeue-Italic" size:14.0f];
}
else
{
replacementFont = [UIFont fontWithName:#"HelveticaNeue-Thin" size:14.0f];
}
[parsedAttributedString addAttribute:NSFontAttributeName value:replacementFont range:range];
}];

Replace the truncation ellipsis of UILabel in iOS 7

How can I replace the truncation ellipsis ("…") of a UILabel in iOS 7 with another attributed character? For example, with a colored ">".
I was hoping Text Kit's NSLayoutManager would make this possible, but it appears UILabel doesn't make it public if it uses it.
Also, can I safely assume that an ellipsis is used as the truncation character in every localisation? Maybe different languages have different truncation characters.
I recommend you use TTTAttributedLabel, just set property "attributedTruncationToken" to your custom string.
I don't think it gives you access to this. I think you would have do handle it manually. For example, use TextKit to determine the size of your string, if it doesn't fit in the available area, truncate it yourself and append a ">" and then put your new string in the label.
NSAttributedString has methods for getting the size of the string.
Let me know if you need any more detail on this..?
I think you can do some customization in -replaceElipsesForLabel method provided by Fonix to get your desired result.
I have written a method to do it, and works in iOS7
-(void)setCustomEllipsis:(NSString*)customEllipsis inLabel:(UILabel*)label with:(NSString*)string{
//Replace the ellipsis
NSMutableString* result = [[NSMutableString alloc] initWithString:#""];
NSArray* strings = [string componentsSeparatedByString:#" "];
for (NSString* s in strings) {
CGRect newSize = [[NSString stringWithFormat:#"%#%#%#",result,s,customEllipsis] boundingRectWithSize:CGSizeMake(label.frame.size.width,0) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:label.font} context:nil];
if (newSize.size.height < label.frame.size.height) {
[result appendString:s];
[result appendString:#" "];
}else{
[result appendString:customEllipsis];
break;
}
}
[label setText:result];
//Set different font to the ellipsis
const CGFloat fontSize = 13;
UIFont *boldFont = [UIFont boldSystemFontOfSize:fontSize];
UIFont *regularFont = [UIFont systemFontOfSize:fontSize];
UIColor *foregroundColor = [UIColor lightGrayColor];
NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:regularFont, NSFontAttributeName,foregroundColor, NSForegroundColorAttributeName, nil];
NSDictionary *subAttrs = [NSDictionary dictionaryWithObjectsAndKeys:boldFont, NSFontAttributeName, nil];
const NSRange range = [label.text rangeOfString:customEllipsis];
NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:result
attributes:attrs];
[attributedText setAttributes:subAttrs range:range];
[label setAttributedText:attributedText];
}

Core Text in UITableviewCell's content overlapping and repeating and superimpose on the other cells

I am using Core Text to add text to UITableviewCell's content but arabic content seems to be overlapping and repeating itself as I scroll and superimpose on the other cells.
I am also using other elements on the page which appear just fine and are not repeating . Just the Core Text seems to be repeating.
I cant figure out why .
Here is my code:
- (CTFontRef)newCustomFontWithName:(NSString *)aFontName
ofType:(NSString *)type
attributes:(NSDictionary *)attributes {
NSString *fontPath = [[NSBundle mainBundle] pathForResource:aFontName ofType:type];
NSData *data = [[NSData alloc] initWithContentsOfFile:fontPath];
CGDataProviderRef fontProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
CGFontRef cgFont = CGFontCreateWithDataProvider(fontProvider);
CGDataProviderRelease(fontProvider);
CTFontDescriptorRef fontDescriptor = CTFontDescriptorCreateWithAttributes((__bridge CFDictionaryRef)attributes);
CTFontRef font = CTFontCreateWithGraphicsFont(cgFont, 0, NULL, fontDescriptor);
CFRelease(fontDescriptor);
CGFontRelease(cgFont);
return font;
}
- (CATextLayer *)customCATextLayer:(NSString *)textString {
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:24.f], (NSString *)kCTFontSizeAttribute,
[NSNumber numberWithInt:1], (NSString *)kCTLigatureAttributeName,
nil];
CTFontRef font = [self newCustomFontWithName:#"me_quranKer6"
ofType:#"ttf"
attributes:attributes];
CATextLayer *normalTextLayer = [[CATextLayer alloc] init];
normalTextLayer.font = font;
normalTextLayer.string = textString;
normalTextLayer.wrapped = YES;
normalTextLayer.foregroundColor = [[UIColor blackColor] CGColor];
normalTextLayer.fontSize = 24.f;
normalTextLayer.alignmentMode = kCAAlignmentCenter;
normalTextLayer.frame = CGRectMake(0.f, 10.f, 320.f, 32.f);
CFRelease(font);
return normalTextLayer;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
QuranVersesViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"verseCell"];
Verse *verse = [self.fetchedResultsController objectAtIndexPath:indexPath];
//English Content starts
NSMutableAttributedString * englishAttributedString;
if (!englishAttributedString)
englishAttributedString = [[NSMutableAttributedString alloc] initWithString:#""];
NSMutableAttributedString * englishSubtitleAttributedString;
NSMutableAttributedString * englishVerseAttributedString;
if (!englishVerseAttributedString)
englishVerseAttributedString = [[NSMutableAttributedString alloc] initWithString:verse.english_version];
NSMutableAttributedString * englishFootnoteAttributedString;
if (!englishFootnoteAttributedString)
englishFootnoteAttributedString = [[NSMutableAttributedString alloc] init];
NSString *englishString = #"";
if(verse.subtitle.length>0)
{
NSMutableParagraphStyle *mutParaStyle=[[NSMutableParagraphStyle alloc] init];
[mutParaStyle setAlignment:NSTextAlignmentCenter];
englishSubtitleAttributedString = [[NSMutableAttributedString alloc] initWithString:verse.subtitle];
[englishSubtitleAttributedString addAttributes:[NSDictionary dictionaryWithObject:mutParaStyle
forKey:NSParagraphStyleAttributeName]
range:NSMakeRange(0,[[englishSubtitleAttributedString string] length])];
[englishAttributedString appendAttributedString:englishSubtitleAttributedString];
[englishAttributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"Arial" size:30] range:NSRangeFromString(verse.subtitle)];
NSLog(#"text us %#", englishAttributedString);
}// englishString = [englishString stringByAppendingString:[NSString stringWithFormat:#"%#\n\n", verse.subtitle]];
[englishAttributedString appendAttributedString:englishVerseAttributedString];
englishString = [englishString stringByAppendingString:[NSString stringWithFormat:#"[%#:%#] %#\n", verse.whichSura.sura_no, verse.verse_no, verse.english_version]];
if(verse.footnote.length>0)
englishString = [englishString stringByAppendingString: [NSString stringWithFormat:#"\n%#\n", verse.footnote]];
englishString = [englishString stringByReplacingOccurrencesOfString:#"“" withString:#"\"" ];
englishString = [englishString stringByReplacingOccurrencesOfString:#"_" withString:#"\n" ];
cell.quranVerseEnglishTextView.attributedText = englishAttributedString;
[cell.quranVerseEnglishTextView autoResizeWithMaxWidth:MAX_TEXT_WIDTH];
cell.quranVerseEnglishTextView.backgroundColor = [UIColor clearColor];
//English Content starts
//Arabic Content
CATextLayer *arabicTextLayer = [self customCATextLayer:verse.arabic_version];
[cell.arabicView.layer addSublayer:arabicTextLayer];
return cell;
}
I was facing the same problem until I read up about NSAttributedStrings (made available in iOS 6) on this tutorial here.
The following code will solve your issue:
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:info.text attributes:#{ NSFontAttributeName : [UIFont fontWithName:#"Scheherazade" size:32], NSLigatureAttributeName: #2}];
cell.textLabel.attributedText = attributedString;
Out of curiosity, would I be correct to say that you opted to use CoreText because of difficulties in rendering embedded arabic fonts? I ventured the guess because I was attempting to use a similar method as you have done in your code when faced with that exact problem for a Quran app that I'm currently developing. If this so then I can confirm that using NSAttributedString also solves the problem. If you notice in the code above I've also set the NSLigatureAttributeName to 2 which according to the official Apple Class Reference Documentation means 'all ligatures'. Just note that this is something that I'm currently testing and I have yet to see the effects of this but I know that ligatures is a common problem in the rendering of some arabic fonts on certain platforms.
While on the subject, another common problem you may be facing is the line-spacing of arabic text and the slight overlapping of multi-line text and I've found that NSAttributedString can also be a good solution when used together with NSParagraphStyle (Hooray again for NSAttributedString!). Simply modify the above code as below:
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:info.text attributes:#{ NSFontAttributeName : [UIFont fontWithName:#"Scheherazade" size:32], NSLigatureAttributeName: #2}];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setLineSpacing:20];
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [info.text length])];
cell.textLabel.attributedText = attributedString;
Hope this helps you or anyone else out there!
EDIT - Adding this helpful post on Common Mistakes With Adding Custom Fonts to Your iOS App for reference as a "checklist" when adding custom fonts on iOS.
Actually fixed the issue myself by adding the following line in cellforRowAtIndexPath:
if (cell == nil)
{
cell = [[QuranVersesViewCell alloc] init];
.....
and also did all the initialization and setting only when the cell was nil. And MOST importantly tagged the view layer and set the text for only the matching tagged view...

Setting custom font in UITextView with attributed string

I have a UITextView which contains an attributed string configured through storyboard. Now i want a custom font to be applied. I am doing it through code
textView.font = [UIFont fontWithName:kCustomFont size:textView.font.pointSize];
The problem is fonts get changed losing all the attributes. How do i fix it?
(Working on iOS 5 and above)
What's in your kCustomFont? If the FontName is wrong, even a single Character, the standard SystemFont will be used.
You should change it via NSMutableAttributedString's attributes.
I.e. use something like:
NSMutableAttributedString *mutableString = [[NSMutableAttributedString alloc] initWithAttributedString:textView.text];
NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil];
[mutableSrting addAttributes:attrs range:NSMakeRange(0, [mutableString length])];
textView.attributedText = mutableString;
[mutableString release];

Resources