How to make TTTAttributedLabel align center programatically in IOS - ios

I am developing an app where I have a string that consists of tags with prefix #.
I am using TTTAttribute Label to add links to words which are having prefix # in a given string.
When I added links to TTTAttribute label. It successfully added and when clicking on that I am able to get that selected word having prefix # in that string..
But I was not able to align center the TTTAttribute label based on string length..
The default property
attributedLabel.verticalAlignment=TTTAttributedLabelVerticalAlignmentCenter;
is not working while applying links..I want the label align center based on its length as shown below..
If it is normal TTTAttribute label without applying links then default align property is applying correctly..
Here is the code I used for adding links..
- (void)viewDidLoad
{
[super viewDidLoad];
NSRange matchRange;
NSString *tweet = #"#MYTWEET ,#tweet, #fashion #Share";
NSScanner *scanner = [NSScanner scannerWithString:tweet];
if (![scanner scanUpToString:#"#" intoString:nil]) {
// there is no opening tag
}
NSString *result = nil;
if (![scanner scanUpToString:#" " intoString:&result]) {
// there is no closing tag
}
//#"theString is:%#",result);
NSArray *words = [tweet componentsSeparatedByString:#" "];
TTTAttributedLabel *attributedLabel=[[TTTAttributedLabel alloc]initWithFrame:CGRectMake(5, 200, 320, 40)];
attributedLabel.textAlignment=NSTextAlignmentCenter;
attributedLabel.text=tweet;
words = [tweet componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#",0123456789`~!#$%^&*()_-+=.></?;:'* "]];
for (NSString *word in words)
{
if ([word hasPrefix:#"#"])
{
//#"word %#",word);
// Colour your 'word' here
matchRange=[tweet rangeOfString:word];
[attributedLabel addLinkToURL:[NSURL URLWithString:word] withRange:matchRange];
[tagsarray addObject:word];
}
}
attributedLabel.delegate=self;
}
- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithURL:(NSURL *)url
{
//#"result ==== %#",url);
NSString *webString=[NSString stringWithFormat:#"%#",url];
NSString *tagstring = [webString stringByReplacingOccurrencesOfString:#"#" withString:#""];
NSLog(#"Tag String is:%#",tagstring);
}
I don't want to resize the frames of TTTAttribute label..
Any suggestions or help will be appreciated..
Thanks in Advance..

You need to set the link attributes with the paragraph style set:
NSMutableParagraphStyle* attributeStyle = [[NSMutableParagraphStyle alloc] init];
attributeStyle.alignment = NSTextAlignmentCenter;
NSDictionary *attributes = #{NSFontAttributeName:[UIFont fontWithName:#"Helvetica Neue" size:11], NSForegroundColorAttributeName:[UIColor colorWithRed:0.324 green:0.0 blue:0.580 alpha:1.0], NSParagraphStyleAttributeName:attributeStyle};
[self.atributedLabel setLinkAttributes:attributes];

Its very simple, use the following code:
attributedLabel.textAlignment = NSTextAlignmentCenter;

Related

Multiple Attributes (Different Text Sizes, Font and Offset) for UILabel Text in Objective C

I want to do something similar like:
the text are not fixed they will change at run time.
Need your thoughts!
Thanks in advance!
After searching a lot, I have end up with
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
previousRandom = -1;
// NEEDY TALL BORING COOL CHEAP AWESOME HANDSOME SEXY SMART SMELLY
NSString *strForText = #"NEEDY TALL BORING COOL CHEAP AWESOME HANDSOME SEXY SMART SMELLY HAPPY RICH FUNNY SEXY SMART SMELLY HAPPY RICH FUNNY";
self.labelForText.attributedText = [[NSAttributedString alloc]initWithString:strForText];
NSArray *arrayForText = [self.labelForText.text componentsSeparatedByString:#" "];
for (NSString *str in arrayForText) {
[self makeTextRandmolyFocused:self.labelForText andString:str];
}
}
// making the $ prefix
-(void)makeTextRandmolyFocused:(UILabel *)label andString:(NSString *)subString {
NSRange range = [label.text rangeOfString:subString];
NSArray *arrayForFontSize = #[#"18",#"11",#"16",#"13",#"14",#"20"];
NSArray *arrayForFontName = #[#"HelveticaNeue-Medium",#"HelveticaNeue-Light",#"HelveticaNeue-Bold",#"HelveticaNeue-Medium",#"HelveticaNeue-Medium",#"HelveticaNeue-Bold"];
NSArray *arrayForBaselineOffset = #[#"2.3",#"1.2",#"2.5",#"1.5",#"3.5",#"0"];
int randomPosition;
do {
randomPosition = arc4random_uniform(5);
} while (randomPosition == previousRandom);
previousRandom = randomPosition;
NSNumber *baselineOffSet =[NSNumber numberWithUnsignedInteger:[arrayForBaselineOffset[randomPosition] integerValue]];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:3.0];
[style setAlignment:NSTextAlignmentCenter];
float spacing = 2.5f;
NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];
[attributedText setAttributes:#{
NSFontAttributeName:[UIFont fontWithName:arrayForFontName[randomPosition] size:[arrayForFontSize[randomPosition] floatValue]],
NSBaselineOffsetAttributeName:baselineOffSet,
NSParagraphStyleAttributeName:style,
NSKernAttributeName:#(spacing)
}
range:range];
label.attributedText = attributedText;
}
Which gives the output as:

How to Convert HTML String to the Formatted String in Objective C

I am using the following code it just eliminating the HTML tags but does not format string. How to format as it is shown in Html.
-(NSString *)convertHTML:(NSString *)html {
NSScanner *myScanner;
NSString *text = nil;
myScanner = [NSScanner scannerWithString:html];
while ([myScanner isAtEnd] == NO) {
[myScanner scanUpToString:#"<" intoString:NULL] ;
[myScanner scanUpToString:#">" intoString:&text] ;
html = [html stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#"%#>", text] withString:#""];
}
//
html = [html stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
return html;
}
Try this one.this might be helpful
textview= [[UITextView alloc]initWithFrame:CGRectMake(10, 130, 250, 170)];
NSString *str = [NSString stringWithFormat:#"<font color='red'>A</font><br/> shared photo of <font color='red'>B</font> with <font color='red'>C</font>, <font color='red'>D</font> "];
[textview setValue:str forKey:#"contentToHTMLString"];
textview.textAlignment = NSTextAlignmentLeft;
textview.editable = NO;
textview.font = [UIFont fontWithName:#"Verdana" size:20.0];
i would recommend using a third party library for that like https://github.com/mwaterfall/MWFeedParser/blob/master/Classes/NSString%2BHTML.m
and than later use it like this:
NSString *string = [#"<b>Your HTML String</b>" stringByConvertingHTMLToPlainText];
There might be a better way of doing this but here is my run on this.
1. scan the html string for the html tags
2. create attributed string for each html tag
3. find all the occurrences of the tag in the string and apply the attributes to them in attributed string.
Here is my sample code to detect break and bold tag
//This method returns an array of occurrence of the tag in string
- (NSArray *)arrayOfStringFromString:(NSString *)string enclosedWithinString:(NSString *)stringOne andString:(NSString *)stringTwo{
NSError *error = NULL;
NSString *pattern =[NSString stringWithFormat:#"%#(.*?)%#",stringOne,stringTwo];
NSRange range = NSMakeRange(0, string.length);
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *matches = [regex matchesInString:string options:NSMatchingReportProgress range:range];
NSMutableArray *subStringArray = [NSMutableArray array];
[matches enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[NSTextCheckingResult class]])
{
NSTextCheckingResult *match = (NSTextCheckingResult *)obj;
NSRange matchRange = match.range;
[subStringArray addObject:[string substringWithRange:matchRange]];
}
}];
return subStringArray;
}
//This method returns the attributed string
- (NSMutableAttributedString*)attributedStringFromHTMLString:(NSString *)htmlString andFontSize:(float)size
{
htmlString = [[self stringByDecodingXMLEntities:htmlString] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSArray *subStringArray = [self arrayOfStringFromString:htmlString enclosedWithinString:#"<b>" andString:#"</b>"];
UIFont *lightFont = [UIFont fontWithName:#"HelveticaNeue-Light" size:size];
UIFont *mediumFont = [UIFont fontWithName:#"HelveticaNeue-Medium" size:size];
htmlString = [[[htmlString stringByReplacingOccurrencesOfString:#"<b>" withString:#""] stringByReplacingOccurrencesOfString:#"</b>" withString:#""] stringByReplacingOccurrencesOfString:#"<br>" withString:#"\n"];
NSArray *otherHtmlTags = [self arrayOfStringFromString:htmlString enclosedWithinString:#"<" andString:#">"];
for (NSString *otherHtmlString in otherHtmlTags) {
[htmlString stringByReplacingOccurrencesOfString:otherHtmlString withString:#""];
}
htmlString = [htmlString stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:htmlString attributes:#{NSFontAttributeName:lightFont}];
for (NSString *string in subStringArray) {
[attributedString addAttributes:#{NSFontAttributeName:mediumFont} range:[htmlString rangeOfString:string]];
}
return attributedString;
}
-(NSString *) stringByStrippingHTML {
NSRange r;
NSString *s = [[self copy] autorelease];
while ((r = [s rangeOfString:#"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
s = [s stringByReplacingCharactersInRange:r withString:#""];
return s;
}
use this method its work for me
NSAttributedString can be initialised with HTML and will display it just fine.
If you want to remove tags, code that replaces tags in the string repeatedly runs in O (n^2), that is it will crawl for large strings. You need to have a mutable output string, and append bits to it as needed, to get linear time.
You can look for "<" and ">" characters. You then need to find which tags you have, because for some tags, everything between the start and end tag has to be deleted as well, or you end up with random rubbish.
You need to handle somehow.
And when you are done, you need to replace all & escape sequences with the correct characters.

CGRect for selected UITextRange adjustment for multiline text?

I've used this answer in order to create a CGRect for a certain range of text.
In this UITextView I've set it's attributedText (so I've got a bunch of styled text with varying glyph sizes).
This works great for the first line of text that's left aligned, but it has some really strange results when working with NSTextAlignmentJustified or NSTextAlignmentCenter.
It also doesn't calculate properly when the lines wrap around or (sometimes) if there are \n line breaks.
I get stuff like this (this is center aligned):
When instead I expect this:
This one has a \n line break - the first two code bits were highlighted successfully, but the last one more code for you to see was not because the text wrapping isn't factored into the x,y calculations.
Here's my implementation:
- (void)formatMarkdownCodeBlockWithAttributes:(NSDictionary *)attributesDict
withHighlightProperties:(NSDictionary *)highlightProperties
forFontSize:(CGFloat)pointSize
{
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"`.+?`" options:NO error:nil];
NSArray *matchesArray = [regex matchesInString:[self.attributedString string] options:NO range:NSMakeRange(0, self.attributedString.length)];
for (NSTextCheckingResult *match in matchesArray)
{
NSRange range = [match range];
if (range.location != NSNotFound) {
self.textView.attributedText = self.attributedString;
CGRect codeRect = [self frameOfTextRange:range forString:[[self.attributedString string] substringWithRange:range] forFontSize:pointSize];
UIView *highlightView = [[UIView alloc] initWithFrame:codeRect];
highlightView.layer.cornerRadius = 4;
highlightView.layer.borderWidth = 1;
highlightView.backgroundColor = [highlightProperties valueForKey:#"backgroundColor"];
highlightView.layer.borderColor = [[highlightProperties valueForKey:#"borderColor"] CGColor];
[self.contentView insertSubview:highlightView atIndex:0];
[self.attributedString addAttributes:attributesDict range:range];
//strip first and last `
[[self.attributedString mutableString] replaceOccurrencesOfString:#"(^`|`$)" withString:#" " options:NSRegularExpressionSearch range:range];
}
}
}
- (CGRect)frameOfTextRange:(NSRange)range forString:(NSString *)string forFontSize:(CGFloat)pointSize
{
self.textView.selectedRange = range;
UITextRange *textRange = [self.textView selectedTextRange];
CGRect rect = [self.textView firstRectForRange:textRange];
//These three lines are a workaround for getting the correct width of the string since I'm always using the monospaced Menlo font.
rect.size.width = ((pointSize / 1.65) * string.length) - 4;
rect.origin.x+=2;
rect.origin.y+=2;
return rect;
}
Oh, and in case you want it, here's the string I'm playing with:
*This* is **awesome** #mention `code` more \n `code and code` #hashtag [markdown](http://google.com) __and__ #mention2 {#FFFFFF|colored text} This**will also** work but ** will not ** **work** Also, some `more code for you to see`
Note: Please don't suggest I use TTTAttributedLabel or OHAttributedLabel.
I think all your problems are because of incorrect order of instructions.
You have to
Set text aligment
Find required substrings and add specific attributes to them
And only then highlight strings with subviews.
Also you will not need to use "a workaround for getting the correct width of the string since I'm always using the monospaced Menlo font" in such a case.
I have simplified your code a little to make it more understandable.
Result:
- (void)viewDidLoad
{
[super viewDidLoad];
NSDictionary *basicAttributes = #{ NSFontAttributeName : [UIFont boldSystemFontOfSize:18],
NSForegroundColorAttributeName : [UIColor blackColor] };
NSDictionary *attributes = #{ NSFontAttributeName : [UIFont systemFontOfSize:15],
NSForegroundColorAttributeName : [UIColor darkGrayColor]};
_textView.attributedText = [[NSAttributedString alloc] initWithString:
#"*This* is **awesome** #mention `code` more \n `code and code` #hashtag [markdown](http://google.com) __and__ #mention2 {#FFFFFF|colored text} This**will also** work but ** will not ** **work** Also, some `more code for you to see`" attributes:attributes];
_textView.textAlignment = NSTextAlignmentCenter;
[self formatMarkdownCodeBlockWithAttributes:basicAttributes];
}
- (void)formatMarkdownCodeBlockWithAttributes:(NSDictionary *)attributesDict
{
NSMutableString *theString = [_textView.attributedText.string mutableCopy];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"`.+?`" options:NO error:nil];
NSArray *matchesArray = [regex matchesInString:theString options:NO range:NSMakeRange(0, theString.length)];
NSMutableAttributedString *theAttributedString = [_textView.attributedText mutableCopy];
for (NSTextCheckingResult *match in matchesArray)
{
NSRange range = [match range];
if (range.location != NSNotFound) {
[theAttributedString addAttributes:attributesDict range:range];
}
}
_textView.attributedText = theAttributedString;
for (NSTextCheckingResult *match in matchesArray)
{
NSRange range = [match range];
if (range.location != NSNotFound) {
CGRect codeRect = [self frameOfTextRange:range];
UIView *highlightView = [[UIView alloc] initWithFrame:codeRect];
highlightView.layer.cornerRadius = 4;
highlightView.layer.borderWidth = 1;
highlightView.backgroundColor = [UIColor yellowColor];
highlightView.layer.borderColor = [[UIColor redColor] CGColor];
[_textView insertSubview:highlightView atIndex:0];
}
}
}
- (CGRect)frameOfTextRange:(NSRange)range
{
self.textView.selectedRange = range;
UITextRange *textRange = [self.textView selectedTextRange];
CGRect rect = [self.textView firstRectForRange:textRange];
return rect;
}
I just had to do something similar to this. Assuming you are using iOS 7:
// Build the range that you want for your text
NSRange range = NSMakeRange(location, length);
// Get the substring of the attributed text at that range
NSAttributedString *substring = [textView.attributedText attributedSubstringFromRange:range];
// Find the frame that would enclose the substring of text.
CGRect frame = [substring boundingRectWithSize:maxSize
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
context:nil];
This should use the NSTextAlignment assigned to the attributed string.
As #Avt answered https://stackoverflow.com/a/22572201/3549781 this question. I'm just answering for the newline problem. This newline problem occurs on iOS 7+ even if you use
[self.textView selectedTextRange] or [self.textView positionFromPosition: offset:]
We just have to ensure the layout of the textView before calling firstRectForRange by
[self.textView.layoutManager ensureLayoutForTextContainer:self.textView.textContainer];
Courtesy : https://stackoverflow.com/a/25983067/3549781
P.S : At first I added this as a comment to the question. As most people don't read comments I added this as an answer.

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

Select Bold and Italicized text from textField

How can I select only bold and italicized text entered by user in a textField/textView ?
We can make a selected text bold, italicized, underline and any combination of these three but what about its vice-versa.
*This is not specific to Mac OSX or iOS, solution in either one is good for me.
EDIT:
I tried by reading the text in attributed string as :
NSAttributedString *string=self.textView.string;
But as textView and textField returns NSString so all formatting is gone.
on iOS use attributedText properties with labels/textfields
on OSX use attributedStringValue
you can then enumerate through the attributedText's attributes and check each attribute. Ill whip up some code (osx & iOS)
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:#"none "];
id temp = [[NSAttributedString alloc] initWithString:#"bold " attributes:#{NSFontAttributeName: [UIFont boldSystemFontOfSize:12]}];
[str appendAttributedString:temp];
temp = [[NSAttributedString alloc] initWithString:#"italic " attributes:#{NSFontAttributeName: [UIFont italicSystemFontOfSize:12]}];
[str appendAttributedString:temp];
temp = [[NSAttributedString alloc] initWithString:#"none " attributes:#{NSFontAttributeName: [UIFont systemFontOfSize:12]}];
[str appendAttributedString:temp];
temp = [[NSAttributedString alloc] initWithString:#"bold2 " attributes:#{NSFontAttributeName: [UIFont boldSystemFontOfSize:12]}];
[str appendAttributedString:temp];
self.label.attributedText = str;
NSMutableString *italics = [NSMutableString string];
NSMutableString *bolds = [NSMutableString string];
NSMutableString *normals = [NSMutableString string];
for (int i=0; i<str.length; i++) {
//could be tuned: MOSTLY by taking into account the effective range and not checking 1 per 1
//warn: == might work now but maybe i'd be cooler to check font traits using CoreText
UIFont *font = [str attribute:NSFontAttributeName atIndex:i effectiveRange:nil];
if(font == [UIFont italicSystemFontOfSize:12]) {
[italics appendString:[[str mutableString] substringWithRange:NSMakeRange(i, 1)]];
} else if(font == [UIFont boldSystemFontOfSize:12]){
[bolds appendString:[[str mutableString] substringWithRange:NSMakeRange(i, 1)]];
} else {
[normals appendString:[[str mutableString] substringWithRange:NSMakeRange(i, 1)]];
}
}
NSLog(#"%#", italics);
NSLog(#"%#", bolds);
NSLog(#"%#", normals);
Now here is how to find it. Deducing a selection range from this should be easy peasy :)
Note: you can only have a continuous selection! neither on osx nor on ios can you select n parts of a textfield/textview

Resources