Out of bound error adding link to nsattributedstrings in iOS - ios

I have the following code setup in iOS using objective C, however the part addint the link only works for ranges starting at 30 or less. The length of short_content should always be at least 100 words.
NSString *short_content = [self getFirstNWords:100 :content];
NSString *link = #" \nClick here to read more ";
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:[short_content stringByAppendingString:link]];
[str addAttribute: NSLinkAttributeName value:#"http://mytest.com/" range:NSMakeRange(str.length - 100, short_content.length)];

If you want to set the range of the "link" part of the string, then you want:
[str addAttribute: NSLinkAttributeName value:#"http://mytest.com/" range:NSMakeRange(str.length - link.length, link.length)];

Related

Objective-C: Equivalent to stringWithFormat for NSMutableAttributedString

I am trying to add a hyperlink in a string. I have a localized string and I put %# to format my string. When I add the attributed string into my string, the attributed format gives the raw result which is NSLink = "https://www.example.com". I could not find an attributed string formatter the same as the string formatter. How can I achieve the same behaviour in my case?
Code:
NSMutableAttributedString * str = [[NSMutableAttributedString alloc] initWithString:#"Example"];
[str addAttribute: NSLinkAttributeName value: #"https:/www.example.com" range: NSMakeRange(0, str.length)];
NSMutableAttributedString *originalStr = [[NSMutableAttributedString alloc] initWithString: self.pageDescriptions[3].localized];
pageContentViewController.messageText = [NSString stringWithFormat:self.pageDescriptions[index].localized, str];
stringWithFormat: is only doing substitutions of formatters. So if your formatters are simple enough, like a %#, you can just search for it with rangeOfString: and do the substitution yourself with replaceCharactersInRange:withAttributedString:.
NSMutableAttributedString *strWithLink = [[NSMutableAttributedString alloc] initWithString:#"Example"];
[strWithLink addAttribute:NSLinkAttributeName value:#"https:/www.example.com" range:NSMakeRange(0, strWithLink.length)];
NSMutableAttributedString *strWithFormat = [[NSMutableAttributedString alloc] initWithString:#"hello %# world"];
[strWithFormat replaceCharactersInRange:[strWithFormat.string rangeOfString:#"%#"] withAttributedString:strWithLink];
The result here in strWithFormat kept the attributes of strWithLink.
Note: this won't work correctly if your format is complex, like with %%# %# %%#, because it will replace the first occurrence of %#, while stringWithFormat: would have replaced the middle occurrence.
There isn't one. You create the NSAttributedString by hand, or you create an extension that does what you want if you do this a lot.

open a web link from different text in a text view

I have an iOS app in which the text from a text view is too long to fit. So I am trying to link the web address to the text in the textView.
Here is what I have.
NSURL *URL = [NSURL URLWithString:#"azgovernor.gov/engage/form/contact-governor-ducey"];
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:#"Email Governor"];
[str addAttribute: NSLinkAttributeName value:URL range: NSMakeRange(0, str.length)];
govemail.attributedText = str;
The Email Governor shows up in the TextView as hyperlink(blue link) and when I touch it, it reacts.
However, the link doesn't respond and I get this message:
Could not find any actions for URL azgovernor.gov/engage/form/contact-governor-ducey without any result.
If I put this address into Safari it opens the page fine. What do I need to do to make this work?
try this:
NSAttributedString *str = [[NSAttributedString alloc] initWithString:#"http://azgovernor.gov/engage/form/contact-governor-ducey"];
govemail.dataDetectorTypes = UIDataDetectorTypeLink;
govemail.editable = NO;
govemail.attributedText = str;

How to change case of an NSMutableAttributedString in Objective-C?

I have a NSMutableAttributedString that contain values in lower case letters. I need to convert all the lowercase letters to uppercase. We can solve this using uppercaseString for normal string as:
[string uppercaseString];
How can I change my case for NSMutableAttributedString? Thanks!
Hope the below code snippet may help you
NSMutableAttributedString * linkString = [[NSMutableAttributedString alloc]initWithString:#"Google"];
NSString * strings = [[linkString string]uppercaseString];
[linkString replaceCharactersInRange:NSMakeRange(0, [linkString length]) withString:strings];
NSLog(#"UpperCase %#",linkString);
NSMutableAttributedString class doesn't have uppercaseString method. So you can use like this..
NSString *str = #"objective-c";
str = [str uppercaseString];
NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:str];
NSLog(#"Attributed String %#",attStr);
And You wanna upper latter in particular range then do something like this...
[attStr replaceCharactersInRange:NSMakeRange(0, 1) withString:#"O"];

Highlight selected character dynamically in iOS

I want to highlight selected character in iOS, as you an see in iPhone iOS 7 Notes app.
When you search for particular text the search character will be highlighted in the result displayed in UITableView.
Example:
"This is my name"
h - should 've blue color
y - should 've red color
The character customisation should be dynamic. I hope I've briefed enough.
Looking for excellent response buddies!
Try having a look at TextKit
This is a nice website that shows you the basics
I hope I understood your question..
You can easily achieve this by setting an attributed string to the text label in a UITableViewCell that shows an entry of your search results.
You would need to calculate ranges of the substrings that should be highlighted. You can do it using regular expressions as I wrote in my sample code. This way you can support multiple occurrences of the substring in a string.
Then, when you have the ranges you just apply special attributes and set the cell label's attributedText property.
The code could look like this:
NSString *searchTerm = ...;
NSString *text = #"This is a sample text that is super cool";
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];
NSString *pattern = [NSString stringWithFormat:#"(%#)", searchTerm];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:kNilOptions
error:nil];
NSRange range = NSMakeRange(0, text.length);
[regex enumerateMatchesInString:text
options:kNilOptions
range:range
usingBlock:^(NSTextCheckingResult *result,
NSMatchingFlags flags,
BOOL *stop)
{
NSRange subStringRange = [result rangeAtIndex:1];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor blueColor]
range:subStringRange];
}];
Then it's easy. You just set the UILabel's attributedText when creating a cell in tableView:cellForRowAtIndexPath: method.
This should point you to the right direction.
Use NsMutableAttributedString to highlight characters
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:display];
[str addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange([displayString length], ([details.notificationCount length]+2))];
displayLabel.attributedText = str;

Formatting multi line text in UILabel?

I would like to have label that has 4 lines. If text is not long enough for 4 lines, nothing happens. But if text is 4 lines or longer I want it to have a little different color just for last line.
Is there easy way to do this. I know i can with attributed string change font of label, but how do i get text that is in forth line?
Use NSAttributedString to format paragraphs, lines, words or even single characters how ever you want. To get the text on the 4th line, separate your text on its \n characters.
If you don't have any \n, you can use getLineStart:end:contentsEnd:forRange:, adapted from here
NSString *string = /* assume this exists */;
unsigned length = [string length];
unsigned lineStart = 0, lineEnd = 0, contentsEnd = 0;
NSMutableArray *lines = [NSMutableArray array];
NSRange currentRange;
while (lineEnd < length) {
[string getLineStart:&lineStart end:&lineEnd
contentsEnd:&contentsEnd forRange:NSMakeRange(lineEnd, 0)];
currentRange = NSMakeRange(lineStart, contentsEnd - lineStart);
[lines addObject:[string substringWithRange:currentRange]];
}
EDIT
After rereading the question, this may not be exactly what you are after. Check out the full answer here:
In iOS 6+ you can render attributed strings using the attributedText property of UILabel.
Following a code example:
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:#"Hello. That is a test attributed string."];
[str addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:NSMakeRange(3,5)];
[str addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(10,7)];
[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"HelveticaNeue-Bold" size:20.0] range:NSMakeRange(20, 10)];
label.attributedText = str;
As you can see in the code you can select a different color text for the different range of characters. In your case you can put the different font color for the chars in the string for the last line.
In order to check the range of chars for the last line you can use:
NSUInteger characterCount = [myString length];
And then characterCount divided for number of chars you can put in each line depending on the width of it.

Resources