Attributed string with NSLinkAttribute does not render on the iPhone - ios

We have an attributed string with 3 components, two are basic strings, the third is a link. The string is being rendered by a UITextView. Strangely, the link is invisible on the iPhone, yet renders fine on the iPad. The behavior is consistent regardless of simulator or actual phone.
Attempting to change the color of the link has no effect. Interestingly, setting the underline color will show the underline... but the text is still invisible.
iOS 7, Xcode 5
Here is our code:
// put together our text for the about view, includes link to Facebook
UIFont *font = [UIFont fontWithName:#"Sansation_Bold_Italic" size:aboutText.font.pointSize];
UIFont *linkFont = [UIFont fontWithName:#"Sansation_Italic" size:aboutText.font.pointSize];
NSMutableDictionary* linkAttributes = [[NSMutableDictionary alloc] init];
[linkAttributes setObject:#"https://www.facebook.com/App" forKey:NSLinkAttributeName];
[linkAttributes setObject:[NSNumber numberWithInt:NSUnderlineStyleSingle] forKey:NSUnderlineStyleAttributeName];
[linkAttributes setObject:[UIColor blueColor] forKey:NSStrokeColorAttributeName];
[linkAttributes setObject:[UIColor blueColor] forKey:NSUnderlineColorAttributeName];
[linkAttributes setObject:linkFont forKey:NSFontAttributeName];
NSAttributedString* link = [[NSAttributedString alloc] initWithString:#"Facebook" attributes:linkAttributes];
NSMutableAttributedString* mas = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(#"ABOUTMSG1", nil)];
[mas appendAttributedString:link];
[mas appendAttributedString:[[NSAttributedString alloc] initWithString:NSLocalizedString(#"ABOUTMSG2", nil)]];
[aboutText setAttributedText:mas];
iPhone
iPad
Any thoughts on why the link is not rendering on the iPhone?

For some weird reason the color appears to be `ClClear.
In any case, if you set the linkTextAttributes of your UITextView to empty
(linkTextAttributes = [:] in Swift)
Then you can set custom color to your link as for any other text.

Related

How to size a symbol image in an attributed string

I have a label where I am trying to put a symbol image at the start of the label and then some text after it. This works, but the symbol image never changes size. It doesn't matter what size I provide in the UIImageSymbolConfiguration, it stays small. If I take this code and put the image in a UIImageView, then the image gets larger as expected. Is there something wrong with anything I am doing here related to the symbol image configuration?
UILabel *label = [[UILabel alloc] init];
NSString *title = #"Some Text";
label.adjustsFontForContentSizeCategory = YES;
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:#" %#", title] attributes:#{
NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleBody],
NSForegroundColorAttributeName: [UIColor labelColor]
}];
UIImageSymbolConfiguration *configuration = [UIImageSymbolConfiguration configurationWithFont:[UIFont preferredFontForTextStyle:UIFontTextStyleLargeTitle]];
UIImage *squareImage = [[UIImage systemImageNamed:#"square.fill" withConfiguration:configuration] imageWithTintColor:[UIColor systemBlueColor]];
NSTextAttachment *imageAttachment = [NSTextAttachment textAttachmentWithImage:squareImage];
[string insertAttributedString:[NSAttributedString attributedStringWithAttachment:imageAttachment] atIndex:0];
label.attributedText = string;
I stumbled upon the same issue as I was building a similar feature today. It seems that symbols work slightly differently when embedded in text attachments: it's the font set on the attributed string that determines the size, not the configuration of the symbol itself.
With this in mind, you simply need to make sure the range of the icon in the attributed string has a font set:
UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
[string addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, 1)];
Note that you'll still need to configure the symbol if you intend to render using a different color. In this case, attributed strings will ignore the NSForegroundColorAttributeName attribute when rendering the symbol (resulting in a blank, zero-width symbol). I suspect this is because symbols have hierarchical colors, but I might be wrong.

UILabel.attributedText not show up on iPhone 4 + iOS 7.0.3

Got a iPhone 4 in the field and a strange problem, the UILabel does not show up any text. I tested it on iPhone 4S + iOS 7 simulator, it works fine.
Code:
NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:[colLabel.text copy]];
[attributeString addAttribute:NSUnderlineStyleAttributeName
value:[NSNumber numberWithInt:1]
range:(NSRange){0,[attributeString length]}];
colLabel.text = nil;
colLabel.attributedText = [attributeString copy];
colLabel.font = [UIFont boldSystemFontOfSize:12];
I have checked. Its showing on iPhone 4, there may be something else. Clean build and delete from device and run again
I have been played with the attributed text for a while, and find out something new:
It seems like on iOS 7.0.x, NSUnderlineStyleAttributeName does not play well with other attributes like color or font, once they are bundled together, it just will not show up the text. Only having underline style actually could draw the text like below:
NSAttributedString* attrStr = [[NSAttributedString alloc] initWithString:colLabel.text
attributes:#{NSUnderlineStyleAttributeName:#(NSUnderlineStyleSingle)}];
colLabel.attributedText = attrStr;
But once you add something like
colLabel.backgroundColor = [UIColor greenColor];
or
colLabel.font = [UIFont boldSystemFontOfSize:12];
It just won't show up, unless you make two changes: appended a newline character to your original string, and set the label's numberOfLines to 2.
like:
NSAttributedString* attrStr =
[[NSAttributedString alloc] initWithString:#"TEST\n" // <---
attributes:
#{NSUnderlineStyleAttributeName:#(NSUnderlineStyleSingle),
NSParagraphStyleAttributeName:paragraph}];
UILabel* myLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 0, 0)];
myLabel.backgroundColor = [UIColor greenColor];
myLabel.attributedText = attrStr;
[myLabel sizeToFit];
myLabel.numberOfLines = 2; // <---

UILabel Attributed Text rendering incorrectly

I've been setting a UILabel using attributed text to get the font outlining that I want, and I change the UILabel's attributedText property fairly often. It seems that roughly 50% of the time it appears to render the new text OVER the old text without removing the old one. Right now my code looks like this:
// Attributes initialization
self.labelAttributes = [NSMutableDictionary dictionary];
[self.labelAttributes setObject: [UIFont fontWithName:#"Helvetica Neue" size:21] forKey: NSFontAttributeName];
[self.labelAttributes setObject: [UIColor whiteColor] forKey: NSForegroundColorAttributeName];
[self.labelAttributes setObject: [NSNumber numberWithFloat: -3.0] forKey: NSStrokeWidthAttributeName];
[self.labelAttributes setObject: [UIColor blackColor] forKey: NSStrokeColorAttributeName];
// Clear UILabel attributedString
self.userLabel.attributedText = [[NSAttributedString alloc] initWithString:#"" attributes:self.labelAttributes];
// Also attempted this with nil;
// Set UILabel to string, where self.userName and self.userAge are just regular strings.
NSString *labelString = [NSString stringWithFormat:#"%#, %#", self.userName, self.userAge];
self.userLabel.attributedText = [[NSAttributedString alloc] initWithString:labelString attributes:self.labelAttributes];
When it works, it looks like this:
When it doesn't work, it looks like this:
This appears to be the last user's name, plus the current user's name overlayed on top of each other.
I can't figure out a good way to guarantee the label is cleared, and am not sure how to debug it. (I've tried using visual debugging in XCode 6, but it still thinks it's just one label, with the new user's text as the text attribute.)
It should already be correct by default but you could try it anyway:
self.userLabel.clearsContextBeforeDrawing = YES;
self.userLabel.contentMode = UIViewContentModeRedraw;
Interesting. Don't really know why that isn't working. Your code seems fine. Only thing I can think of is that if this is a label in a table view cell and it being reset after it is offscreen and then on screen? Otherwise, no idea.
Here is another way of doing the same thing that works for me.
NSString *labelString = [NSString stringWithFormat:#"%#, %#", self.userName, self.userAge];
self.userLabel.text = labelString;
NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc]initWithAttributedString:self.userLabel.attributedText];
[attStr addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"Helvetica Neue" size:21] range:NSMakeRange(0, self.userLabel.length)];
[attStr addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(0, self.userLabel.length)];
[attStr addAttribute:NSStrokeWidthAttributeName value:[NSNumber numberWithFloat:-3.0f] range:NSMakeRange(0, self.userLabel.length)];
[attStr addAttribute:NSStrokeColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, self.userLabel.length)];
//or 1 liner
//[attStr addAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:#"Helvetica Neue" size:21], NSFontAttributeName, [UIColor whiteColor], NSForegroundColorAttributeName, [NSNumber numberWithFloat:-3.0f], NSStrokeWidthAttributeName, [UIColor blackColor], NSStrokeColorAttributeName, nil] range:NSMakeRange(0, self.userLabel.length)];
[self.userLabel setAttributedText:attStr];
Also, I don't see why you just can't set the label to have those properties to begin with, (if they are not changing throughout the label).
You could just do:
NSString *labelString = [NSString stringWithFormat:#"%#, %#", self.userName, self.userAge];
self.userLabel.text = labelString;
self.userLabel.font = [UIFont fontWithName:#"Helvetica Neue" size:21];
self.userLabel.textColor = [UIColor blackColor];
//Then set the stroke with one attribute
Hope this helps! Happy coding.
You can do it as followed:
self.userLabel.attributedText = [[NSAttributedString alloc]
initWithString:#"string to both stroke and fill"
attributes:#{
NSStrokeWidthAttributeName: [NSNumber numberWithFloat:-3.0],
NSStrokeColorAttributeName: [UIColor blackColor],
NSForegroundColorAttributeName: [UIColor whiteColor]
}
];
I suspect that the problem is not related with the attributed text. I suspect that the problem is that you are adding a new UILabel in a reused UITableViewCell, instead of reuse the old UILabel.
I think I've seen this happen before with UITableCell reuse and dynamic table cell heights, determined at run time. This happens when cells are being set to height 0, if I remember correctly.
If you're in the above scenario, try turning clipsToBounds to on on the UITableViewCell, or the topmost reused view. Turning on clipsToBounds causes the labels, etc. to not flow out of the view when the containing view's frame size or height has been set to zero.

ios 6.0 setAttributedText crash

- (IBAction)pinFieldChanged:(id)sender {
UITextField *pinField = sender;
float kerninig = 76.0;
NSAttributedString *attributedString =
[[NSAttributedString alloc]
initWithString:pinField.text
attributes:
#{
NSFontAttributeName : [UIFont fontWithName:#"Helvetica Neue" size:36],
NSForegroundColorAttributeName : [UIColor colorWithRed:130.0/255.0 green:130.0/255.0 blue:130.0/255.0 alpha:1.0],
NSKernAttributeName : #(kerninig)
}];
if ([pinField respondsToSelector:#selector(setAttributedText:)]) {
[pinField setAttributedText:attributedString];
}
}
My app is crashing under ios6.0 when i'm trying to set attributed text to text field, though this selector is available iOS 6.0 and later
Can you give me any idea why this could happen?
Thanks in advance!)
iOS5 may be expects a CTFont so use
NSString* s = #"Yo ho ho and a bottle of rum!";
NSMutableAttributedString* mas = [[NSMutableAttributedString alloc] initWithString:s];
__block CGFloat f = 18.0;
CTFontRef basefont = CTFontCreateWithName((CFStringRef)#"Baskerville", f, NULL);
https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/iOS5bookExamples/ch23p689styledText1/p579p593styleText1/RootViewController.m
use below ios 6
NSAttributedString *stringValue= [[NSAttributedString alloc] initWithString:#"cocoalibrary.blogspot.com" attributes:#{NSForegroundColorAttributeName: [UIColor redColor]}];
NSAttributedString is not available below than IOS 6. See this link, you can found this line.
In iOS 6 and later you can use attributed strings to display formatted
text in text views, text fields, and some other controls

UITextView Text size is auto resized while using the NSAttributedString

In the UITextView text,
before highlight the text, its shown the text size as 16. (in the first image)
after the using the NSAttributedString to highlight. highlighted text only show that same size(16) remaining strings show lesser than that the original size (second .
this problem only in the iPod and iPhone deceive . iPad is shown correct format.
code to highlight the UITextView Text
NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObject:[UIFont fontWithName:#"Arial" size:currentTextSize] forKey:NSFontAttributeName];
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:txtview4disp.text];
int startind=[[dict objectForKey:#"BeginIndexPos"]integerValue];
int endind=[[dict objectForKey:#"EndIndexPos"]integerValue];
NSRange rang;
if (startind>=STARTINDEX&&startind<=ENDINDEX) {
if (endind>ENDINDEX) {
int endind2=endind-ENDINDEX;
rang=NSMakeRange(startind-STARTINDEX, (endind-startind)-endind2);
}
else
rang=NSMakeRange(startind-STARTINDEX, endind-startind);
[attrString addAttributes:attrsDictionary range:rang];
[attrString addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:rang];
txtview4disp.attributedText=attrString;
It looks like you skipped the original attributes of your UITextView.
Try replacing this line:
NSMutableAttributedString *attrString =
[[NSMutableAttributedString alloc] initWithString:txtview4disp.text];
with following:
NSMutableAttributedString *attrString =
[[NSMutableAttributedString alloc] initWithAttributedString:txtview4disp.attributedText];

Resources