NSAttributedString Strike attribute not working - ios

I know this question has been asked many times, but none of the answers I read helped me to fix my problem...
In my iOS app, I'm generating a PDF file using default frameworks (UIGraphicsBeginPDFContextToFile...).
Everything works fine, I can change text colors, underlying styles, etc.
But I don't manage to strike a string.
Here's my code:
[toBeConfirmedText addAttributes:#{ NSBaselineOffsetAttributeName: #(0), NSStrikethroughStyleAttributeName: #(NSUnderlineStyleThick), NSStrikethroughColorAttributeName: [UIColor redColor] } range:NSMakeRange(0, toBeConfirmedText.length)];
But that does not work...
Does anyone has an idea?

I should add a comment that your code has no problem in Xcode 10. But because I need to add test codes, so you may treat it as an answer.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"myTest.pdf"];
BOOL result = UIGraphicsBeginPDFContextToFile(filePath, CGRectZero, nil);
UIGraphicsBeginPDFPage();
NSMutableAttributedString * toBeConfirmedText = [[NSMutableAttributedString alloc]initWithString:#"mytest"];
[toBeConfirmedText addAttributes:#{ NSBaselineOffsetAttributeName: #(0), NSStrikethroughStyleAttributeName: #(NSUnderlineStyleThick), NSStrikethroughColorAttributeName: [UIColor redColor] } range:NSMakeRange(0, toBeConfirmedText.length)];
[toBeConfirmedText drawInRect: CGRectMake(0, 0, 600, 200)];
UIGraphicsEndPDFContext();

Related

Bolding an nsstring

I have looked online for ways to bold a NSString and either it's not there or I can't seem to find it. I simply want to bold the word in the NSString but so far, what I have done is not woking:
NSString *player1Name = [[UIFont boldSystemFontOfSize:12] fontName];
I have relied on this to make "player1Name" bold but it doesn't work at all.
When I run it I get this:
Thanks in advance to anyone who helps me figure out the solution.
You can not bold a NSString... Try a NSAttributedString...
NSAttributedString *player1Name = [[NSAttributedString alloc] initWithString:#"name" attributes:#{NSFontAttributeName : [UIFont boldSystemFontOfSize:12]}];
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSAttributedString_Class/
fontName is a property on UIFont
[[UIFont boldSystemFontOfSize:12] fontName]
returns the font name HelveticaNeueInterface-MediumP4
Try this:
NSString *myString = #"My string!";
NSAttributedString *myBoldString = [[NSAttributedString alloc] initWithString:myString
attributes:#{ NSFontAttributeName: [UIFont boldSystemFontOfSize:35.0] }];
Also you can set range for particular text like:
NSString *boldFontName = [[UIFont boldSystemFontOfSize:12] fontName];
NSString *yourString = ...;
NSRange boldedRange = NSMakeRange(2, 4);
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:yourString];
[attrString beginEditing];
[attrString addAttribute:kCTFontAttributeName
value:boldFontName
range:boldedRange];
[attrString endEditing];
You can't make NSString bold. Instead of that you can make UILabel text into bold. Because UILabels are for UI representation & NSStrings are just objects. So make your UILabel bold
[infoLabel setFont:[UIFont boldSystemFontOfSize:16]];

Objective-C created a PDF, can I add background colour?

I created a PDF with the code below:
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filename = #"test.pdf";
NSURL *fileURL = [NSURL fileURLWithPathComponents:[NSArray arrayWithObjects:documentsDirectory, filename, nil]];
CGContextRef pdfContext = CGPDFContextCreateWithURL((CFURLRef)fileURL, NULL, NULL);
CGPDFContextBeginPage(pdfContext, NULL);
UIGraphicsPushContext(pdfContext);
CGRect bounds = CGContextGetClipBoundingBox(pdfContext);
CGContextScaleCTM(pdfContext, 1.0, -1.0);
CGContextTranslateCTM(pdfContext, 0.0, -bounds.size.height);
UIFont *headerFont = [UIFont fontWithName:#"Arial" size:8];
NSDictionary *headerAttributes = #{ NSFontAttributeName: headerFont};
[#"Task" drawAtPoint:CGPointMake(10, 10) withAttributes:headerAttributes];
UIGraphicsPopContext();
CGPDFContextEndPage(pdfContext);
CGPDFContextClose(pdfContext);
My question is, can I add a background colour as an attribute? for this
[#"Task" drawAtPoint:CGPointMake(10, 10) withAttributes:headerAttributes];
I will be adding multiple items and they will all have different background colours, I am just asking if this is possible?
You can definitely do this by using NSAttributedString and the relative properties, but for sanity I would recommend this library. I've found NSAttributedString to be insanely verbose and (personally) have enjoyed having my styling happen in a leaner language. Note that I have nothing to do with this library but it really helped

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.

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...

How do I use HTML.fromhtml in IOS?

I want to make a NSString notification like this: "You must pay 4.00 dollar.".The money has a red color.In Android ,I can use HTML.formhtml do it.But I don't know how to do it in IOS.Who can help me?
try this code
CATextLayer *aTextLayer_= [[[CATextLayer alloc]init] autorelease];
aTextLayer_.frame = CGRectMake(10, 100, 300, 50);
aTextLayer_.backgroundColor=[UIColor clearColor].CGColor;
aTextLayer_.foregroundColor = [[UIColor redColor] CGColor];
aTextLayer_.alignmentMode=kCAAlignmentCenter;
aTextLayer_.contentsScale = [[UIScreen mainScreen] scale];
aTextLayer_ .wrapped=YES;
[aTextLayer_ setAlignmentMode:kCAAlignmentLeft];
UIFont *smallFont = [UIFont systemFontOfSize:25];
CTFontRef ctSmallFont = CTFontCreateWithName((CFStringRef)smallFont.fontName, smallFont.pointSize, NULL);
UIFont *boldFont = [UIFont systemFontOfSize:25];
CTFontRef ctBoldFont = CTFontCreateWithName((CFStringRef)boldFont.fontName, boldFont.pointSize, NULL);
CGColorRef cgColor = [UIColor greenColor].CGColor;
CGColorRef cgColor1 = [UIColor redColor].CGColor;
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
(id)ctSmallFont, (id)kCTFontAttributeName,
cgColor, (id)kCTForegroundColorAttributeName, nil];
NSDictionary *subattributes = [NSDictionary dictionaryWithObjectsAndKeys:
(id)ctBoldFont, (id)kCTFontAttributeName,
cgColor1, (id)kCTForegroundColorAttributeName, nil];
CFRelease(ctBoldFont);
NSString *subString=#"You must pay 4.00 dollar.";
NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:subString attributes:attributes];
[attrStr addAttributes:subattributes range:NSMakeRange(13,4)];
aTextLayer_.string=attrStr;
[self.view.layer addSublayer:aTextLayer_];
If you don't want to use a UIWebView your best options is to use a NSAttributedString.
A naive implementation without caring too much about corner cases and error checking would be something like
NSString * string = #"You must pay 4.00 dollar";
NSString * pattern = #"You must pay (.+) dollar";
NSRegularExpression * regex = [[NSRegularExpression alloc] initWithPattern:pattern options:0 error:NULL];
NSArray * matches = [regex matchesInString:string options:0 range:NSMakeRange(0, string.length)];
NSRange priceRange = [matches[0] rangeAtIndex:1];
NSMutableAttributedString * attrString = [[NSMutableAttributedString alloc] initWithString:string];
[attrString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:priceRange];
Note that I assumed that your patter will always be You must pay (.+) dollar. In case it's different simply adjust the regex in order to retrieve the NSRange of the substring that needs to be stylized.
Then you can use the attributed string as a content of anything accepting a NSAttributedString, for instance UILabel has an attributedText property since iOS 6, therefore you could do something like
yourLabel.attributedText = attrString;
you can add html code to UIWebView
[_webView loadHTMLString:#"<p>You must pay <font color=\"red\">4.00</font> dollar. </p> " baseURL:nil];
try this code
-----------------Alternate Option----------------------------
If this text format is going to be fixed (You must pay XXXX.XXX dollar.) better Create custom component
Create class extend UIView
Add UILable with different font color

Resources