UILabel adding double quotes between number and percent sign - ios

I'm building an iOS app (XCode 9.3.1, iOS 11.3, Swift 3.3), with a UITableView and UITableViewCell, in which I add some UILabel.
If there's a number followed by a space and a percent sign in the label text (e.g. 25 %), it automatically adds a double quote between the number and the percent sign. If there is no space between, I don't have this issue. Same if the space is preceded by letters instead of a number.
self.amorce.frame = CGRect(x: labelX, y: currentY, width: labelWidth, height: 0)
self.amorce.preferredMaxLayoutWidth = self.amorce.frame.width
self.amorce.text = "25% 25 % 32 % 32% bleh% bleh %"
self.amorce.sizeToFit()
Result is :
Anyone ever had this issue or knows how to fix this?
Edit :
If I don't change the font and use the default one, I don't have this problem. Could it be a bug with my font? It's weird because if it's not a number (e.g. twenty %), even though there's a space between, there's no problem.

Related

UILabel sometimes renders NSAttributedString with a 1px tall line above text

This is a bit of an odd issue for me. I'm displaying some complex attributed text in a label and it was working well until recently a small grey line began to appear above certain lines of text like below:
Note that this is distinct from the tableview cell separator and only appears above the rect of the label.
With a bit of debugging, I also noticed the line doesn't appear when I don't have the little blue bracketed "flair" tag:
I am using the following code to add the problematic blue tags:
let captionFont = UIFont.preferredFont(forTextStyle: UIFontTextStyle.caption1);
let offset = (bodyFont.lineHeight / 2) - (captionFont.lineHeight / 2)
attributedString.addAttributes([NSAttributedStringKey.font : captionFont, NSAttributedStringKey.foregroundColor : Constants.linkColor, NSAttributedStringKey.baselineOffset:offset], range: flairRange!)
What am I doing wrong? Is this a CoreText bug?
After a bit of trial and error, I determined the issue only appeared when offset was a decimal value. When I simply replaced my offset line with
let offset = ceil((bodyFont.lineHeight / 2) - (captionFont.lineHeight / 2))
the line no longer appeared. I suspect this is a CoreText bug.

Double check mark similar to Whatsapp's read status

How to make a double check marks in UILabel through
unicode chack mark (U+2713), without any image
To do this with Unicode is not a problem, how to make it similar to whatsapp's read status? how to do letter spacing or remove space beetween two unicode symbol?
You can achieve this using NSAttributedStringKey.kern…
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
label.backgroundColor = .white
label.attributedText = NSAttributedString(string: "✓✓", attributes: [.kern: -6])
From Apple's docs…
The value of this attribute is an NSNumber object containing a floating-point value. This value specifies the number of points by which to adjust kern-pair characters. Kerning prevents unwanted space from occurring between specific characters and depends on the font. The value 0 means kerning is disabled. The default value for this attribute is 0.

Dynamically center 2 lines of text programmatically with roughly equal length per row

My situation is that I have a line of text that can vary in length due to localization. This will need to be displayed on the screen such that each line is roughly of equal length, and is centered.
This is my very long line.
Should look like this
This is my
very long line.
So I took a crack at this and got something that works the way I want it now.
I take a localized string, set it to an empty label, and find out what it's size is. (The orange is just for illustrative purposes)
With the size of the label, I then divide it by 1.8 which gives me some buffer room to account for inconsistent word sizes (again, I don't know what will be here in advance). Finally, I multiply the height by 2.0, and set that as my new frame. Finally, I add it to the view.
This has held up with a few sample strings, though it would need to be revised to handle more than 2 lines (currently, not an issue).
let text = NSLocalizedString("This is my very long line of text.", comment: "")
let instructionLabel = UILabel()
instructionLabel.text = text
instructionLabel.textAlignment = .center
instructionLabel.backgroundColor = .orange
instructionLabel.numberOfLines = 0
let size = instructionLabel.intrinsicContentSize
let newSize = CGSize(width: size.width / 1.8, height: size.height * 2.0)
let rect = CGRect(x: 20, y: 100, width: newSize.width, height: newSize.height)
instructionLabel.frame = rect
view.addSubview(instructionLabel)
Which produces the following output:
And an even longer one:
Just for some variety, this is the second string above, but in Arabic:
You could do this to set alignment.
myLabel.textAlignment = .center
Also set the number of lines to 0. And if you want a specific width, set the preferredMaxLayoutWidth property like so:
myLabel.preferredMaxLayoutWidth = 80
myLabel.numberOfLines = 0
If you want it to work for arbitrary localizations (assuming languages that use spaces), you would need an algorithm that split the text on spaces and then loop through each combination of top and bottom text, measuring its width, to see what gave the most evenly distributed sizing. This feels like overkill.
Having done a fair amount of localization, the better bet is to manually insert \n characters in the .strings file to adjust breaks that aren't visually pleasing. Relying on a fixed width will work for many languages, but won't give you the flexibility you're looking for.

how much pixels dose a character takes in iOS?

I'm trying to automatically layout text on a UILabel view.
The text (such as "abcdefghij") contains ten characters. I want to display it in one single line.
I turned off the Size Class and Auto Layout for convenience, and added following codes to layout the text on the UILabel. It should be ten characters in one line, and the width of the UILabel is equal to the width of the device.
let screenWidth = UIScreen.mainScreen().bounds.width
labelView.frame = CGRect(x: labelView.frame.origin.x, y: labelView.frame.origin.y, width: screenWidth, height: labelView.frame.height)
let string = "abcdefghij"
let stringLength = CGFloat(string.characters.count)
let characterSize = keyboardView.font.pointSize
let characterSpacing = (screenWidth - characterSize * stringLength) / stringLength
let content = NSAttributedString(string: string, attributes: [NSKernAttributeName: characterSpacing])
keyboardView.attributedText = content
But it turns out like this. The width of string is not equal to the screen
I think, the only could be wrong here is the pointSize. It equals to 13.8 while I set the font size to 17.
I don't understand it.
Give me some hints, please.
Thanks for your attention. 😄
By using sizeWithAttributes and boundingRectWithSize(_:options:context:), I finally figured out how it works. But my origin purpose is fitting the 10 characters in one line. The code should calculate the space between the characters, and all the space is same size. Could you give me some advices?
This is what I want to make
Each character occupies different amount of space depending on the character, font and size of the font.
Hence, you can use boundingRectWithSize(_:options:context:) to predict size of the string at runtime, and then take action according to your requirements.

how to set UILabel to specific number of characters

I have a which has width 240 and size of characters is 28, I want to display only 16 characters if string comes more than 16, after 16 characters it should show triple dots just like truncated. I have did following try but it did not work.
if(place_title.length>=16){
place_title.autoresizesSubviews=YES;
}
else{
place_title.autoresizesSubviews=NO;
place_title.adjustsFontSizeToFitWidth=YES;
}
It truncated words around 12 characters. I want to just show 16 character, not to compromise n size of label (to grow size of label) but will compromise on size of string(decrease the size of characters) in label.
Thanks in advance.
Is there a reason you can't do something like
if (place_title.length > 16){
place_title = [[place_title substringToIndex:15] stringByAppendingString:#"..."];
}
rather than trying to get UILabel to do this for you?

Resources