CodeBender
CodeBender

Reputation: 36660

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.

Upvotes: 1

Views: 434

Answers (3)

CodeBender
CodeBender

Reputation: 36660

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:

enter image description here

And an even longer one:

enter image description here

Just for some variety, this is the second string above, but in Arabic:

enter image description here

Upvotes: 2

dmorrow
dmorrow

Reputation: 5694

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.

Upvotes: 0

azizj
azizj

Reputation: 3787

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

Upvotes: 0

Related Questions