Subscript and superscript Strings adding extra space between lines - ios

Adding subscript and superscript to attributed string, making gaps between the lines get bigger than usual. I want all the lines to be equally spaced.
I have attached a screenshot for reference, which can show line gap difference between the first two lines and next two lines because of the subscripts added.
Can u help one help me out in this? Thanks in advance.
if ([start isEqualToString:#"<subscript>"]) {
[attributedString replaceCharactersInRange:replacingRange withString:tempString];
[attributedString addAttribute:(NSString *)kCTSuperscriptAttributeName value:#"-1" range:NSMakeRange(startRange.location, tempString.length)];
}
if ([start isEqualToString:#"<superscript>"]) {
[attributedString replaceCharactersInRange:replacingRange withString:tempString];
NSInteger textheight = 1;
CFNumberRef subscriptHeight = CFNumberCreate(NULL, kCFNumberNSIntegerType, &textheight);
[attributedString addAttribute:(NSString *)NSBaselineOffsetAttributeName value:(__bridge id _Nonnull)(subscriptHeight) range:NSMakeRange(startRange.location, tempString.length)];
}

The RTF tag for this is "\noextrasprl". I don't know if UITextView supports it but you could try assigning this as an attribute for the whole text (don't know if the attributes key will need the backslash or not)é

Related

How to make particular word colored : coming from localized string file of iOS

I would like to make particular word colored like this :
Text in English :-
Same place text in French :-
These text are came from localized string file. And I found solution with the string range property NSMakeRange(0,3) for attributed text from here. This I don't want since text will differ for Localized language string. FYI, I placed text in UITextView.
So how can I achieve this by simple way? Is there any solution that can fix problem in Localized string file itself.
I know this answer is a few years late, but I solved the problem by allowing HTML in my localizable strings. For example:
"emergency" = "This is a test of the <span style=\"color:red\">emergency</span> broadcast system.";
Of course, this alone won't solve the problem, because the localizable string files in IOS don't natively support any sort of HTML/XML annotation. So, you need to process the HTML yourself when you extract the string in your swift code. Here is how I did it:
// Get the localized string
let localized = NSLocalizedString("emergency", comment: "")
// Prepend an html header to the string select the primary font and color.
// The settings on the UITextView or UILabel will be ignored, so you need to do this
let htmlString = "<span style=\"color:yellow;font-size:24px;font-family:-apple-system\">" + localized
// perform the magic to turn the html string into an NSAttributedString
let data = NSString(string: htmlString).data(using: String.Encoding.utf8.rawValue)
do {
let attributedString = try NSAttributedString(data: data!,
options: [
.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
// Show the NSAttributedString in your help UITextView (or anywhere else)
help.attributedText = attributedString
} catch {
print("There was a problem")
}
This example gives you yellow, 24-point, apple system font text. The localizable string marked the word "emergency" as red, and it will be displayed in red in the final display.
Below snippet might be used for achieving yourrequirement
UITextView *textView = //YourTextView
NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithAttributedString: textView.attributedText];
[attributedText addAttribute:NSForegroundColorAttributeName
value:[UIColor redColor]
range:[textView.text rangeOfString:blueString]];
[attributedText addAttribute:NSForegroundColorAttributeName
value:[UIColor blueColor]
range:[textView.text rangeOfString:redString]];
[textView setAttributedText: attributedText];

UILabel word wrap and slashes

I have a multiple lines UILabel. The text contains slash ("/") character. Usually slash is a not breaking character. But UILabel handles it as a breaking one. How to make it non-breakable?
Example
textLabel.lineBreakMode = UILineBreakModeWordWrap;
textLabel.numberOfLines = 2;
textLabel.text = #"Some text with/slash";
This code is rendered as:
Some text with/
slash
Should be rendered as:
Some text
with/slash
For Slash, use this:
textLabel.text = #"Some text with\/slash";
For avoiding word wrap in label, use this;
[textLabel sizeToFit];
Update:
Below comment suggests that I misunderstood the problem here..
Anyhow, if you want to print it in two lines, use next line carriage ..(/r)
textLabel.text =#"Some text \r with/slash";
Working as you wanted.. :)
Let me know if any info needed.. :)

Why are the ranges for my formatted text shifting in iOS 7?

My app includes a text formatting tool that offers buttons for things like bold, italic and color and shows the formatted text by generating an NSAttributedString and setting that to the attributedText property of a UITextView. After the user selects text and taps a button, I get the selectedRange property of the UITextView, then get the current attributedText property of the UITextView, add another attribute to the text based on the selected range, and then assign it back to the attributedText property of the UITextView again.
Starting with iOS 7, my text formatting started displaying at the wrong location in the text, usually shifted a couple characters forward. After some testing I noticed that this only happened after an empty line (e.g., a paragraph of text with two line breaks after it) and the formatting was offset by one character for each empty line proceeding it.
After more testing I found that when I set the attributedText property for the first time, any sequence of two line breaks is changed to a line break, then a "line separator" character (Unicode 8232) and then the second line break. The new characters are definitely added by the attributedText assignment, as I can see from outputting the integer value of each character immediately before and immediately after that action. However, the selectedRange property of the UITextView ignores the line separator characters, so any range that it returns is now incorrect.
I've already found a workaround, which I'll add as an answer in a moment. I'm mainly posting this in case anyone else is having problems with it. Also, I've reported this to Apple as bug 15349335.
I wrote this method to adjust ranges returned by the selectedRange property to account for these extra line separator characters:
- (NSRange)adjustRangeForEmptyLines:(NSRange)range inText:(NSAttributedString *)text byChars:(int)chars {
int emptyLinesBeforeRange = 0;
int emptyLinesWithinRange = 0;
for (int i=0; i<(range.location + range.length); i++) {
int thisCharacter = [text.string characterAtIndex:i];
//NSLog(#"thisCharacter: %i", thisCharacter);
if (thisCharacter == 8232) {
if (i < range.location) {
emptyLinesBeforeRange++;
} else {
emptyLinesWithinRange++;
}
}
}
//NSLog(#"found %i + %i empty lines", emptyLinesBeforeRange, emptyLinesWithinRange);
range.location += (emptyLinesBeforeRange * chars);
range.length += (emptyLinesWithinRange * chars);
return range;
}
I can set the byChars argument to 1 or -1 depending on which way I want to adjust. This has been working for me for a few weeks now, but if anyone has an alternate solution, I'd be curious to see it.

Change Font Family for Specific Characters in my NSString

My project demands that I use a custom Font, but this font have strange images in some characters like ( ) , . / etc...
The design agency said to replace the font in these characters to a more common font like Gill Sans.
So in a NSString = #"(My Favorite's. Love this!)";
I need to have the main custom font for the text and the Gill Sans font for the ( ' . ! and )
Is there a code where I can just pass the string and it returns some NSString with NSAttributedString with the font changes?
Thanks,
here is a sample code:
NSString *displayText = #"(My Favorite's. Love this!)";
NSMutableAttributedString *attributedString = [NSMutableAttributedString attributedStringWithString:displayText];
[attributedString setFont:[UIFont systemFontOfSize:15] range:[displayText rangeOfString:#"."]];
The last line will change the font of the point (.) to system font of size 15. You can search another characters in the string using the same function, and replace another properties of the string with setter methods of the form setX:range: of the NSAttributedString class.
Hope it helps!
use NSAttributedString to set multible font and size for string in ios NSAttributedString Class Reference,example

UILabel lineBreakMode, break at specific character

Is there a way to break the text in a UILabel at a specific character say ";" ??
I don't want it to be broken with Word Wrap or character Wrap.
Sure, just replace all the occurrences of ";" with ";\n" before you show the string.
There is another way which will work in limited circumstances. You can replace your normal spaces (\U+0020) with non-breaking spaces (\U+00A0). This will allow you to limit the number of places your string breaks. For example if you had a string like;
I have a string with two sentences. I want it to preserve the sentences.
By carefully using non-breaking spaces you can get it to break like this;
I have a string with two sentences.
I want it to preserve the sentences.
HOW:
For Strings in InterfaceBuilder:
Go to System Preferences -> Keyboard -> Input Sources -> +
Select the category 'Others' and the keyboard 'Unicode Hex Input'
Select 'Add'
Make sure 'Show Input method in menu bar' is selected.
CLose System Preferences
Go back to XCode and find your string
Using the keyboard menu in your menu bar, select the Unicode keyboard
In your string select a space. Type Option+00a0. A space will appear when you've completed the 4 digit sequence. That space is a non-breaking space. Repeat for all spaces you need to.
For programmatic strings you can just add \U00A0 as appropriate.
You can use (\r) instead of newline (\n) to create a line break.
Set numberOfLines to 0 to allow for any number of lines.
yourLabel.numberOfLines = 0;
Like With in your case just replace ; with ;\n
NSString *string = #"This; is a; NSString";
string = [string stringByReplacingOccurrencesOfString:#";"
withString:#";\n"];
You can't break line using ; this character. if you want to break line then replace this character with \n character.
label.text=[label.text stringByReplacingOccurrencesOfString:#";" withString:#"\n"];
And make
label.numberOfLines = 0.
And Update the label frame
CGSize labelSize = [label.text sizeWithFont:label.font constrainedToSize:label.frame.size lineBreakMode:label.lineBreakMode];
label.frame = CGRectMake(label.frame.origin.x, label.frame.origin.y, label.frame.size.width, labelSize.height);
You can do with combination of newline character and line break.Check the following code,
self.testLabel.text = #"abc;\nabc;";
self.testLabel.numberOfLines = 0;
CGSize labelSize = [self.testLabel.text sizeWithFont:self.testLabel.font
constrainedToSize:self.testLabel.frame.size
lineBreakMode:self.testLabel.lineBreakMode];
self.testLabel.frame = CGRectMake(
self.testLabel.frame.origin.x, self.testLabel.frame.origin.y,
labelSize.width, labelSize.height);

Resources