UILabel Text Not Wrapping
First, the good news: You have set the label to 2 lines and Word Wrap. So it can wrap. Excellent.
Now you must make sure the label is tall enough. Either give it no height constraint, or give it a big enough height constraint that it can accommodate two lines.
Finally, you must limit its width. This is what causes the text to wrap. If you don't limit the label's width, it will just keep growing rightward, potentially continuing off the screen. The limit on the label's width stops this rightward growth and causes the text to wrap (and the label to grow downward instead).
You can limit width in several ways. You can have an actual width constraints. Or you can have a leading constraint and a trailing constraint, to something relatively immovable, such as the superview. And there is a third way: on the Size inspector (which you do also show, at the bottom right of your question), set the Preferred Width (it is shown at the top of the Size inspector): this is the width at which, all other things being equal, the label will stop growing to the right and wrap and grow down instead.
UILabel can not be wrapped and aligned at the same time
You are missing a few constraints.
To get a multiline label to wrap, it must have its width limited (how else would it know the text is too long?).
To get auto layout to adjust the cell's height, you need constraints on the content of the cell to "push down" the bottom of the cell.
So...
- Constrain your top-left label to
Leading: 0
,Top: 0
,Width: 77
(I'm using 77 as the width, based on your images). - Constrain your top-right label to
Leading: 8
(to top-left label's trailing),Top: 0
,Trailing: 0
- Constrain your bottom-left label to
Leading: 0
,Top: 8
(to top-left label's bottom),Width: 77
(or, width equal to top-left label) - Constrain your bottom-right label to
Leading: 8
(to bottom-left label's trailing),Top: 8
(to top-right label's bottom, orTop: 0
to top of bottom-left label),Trailing: 0
then, add Bottom
constraints of >= 0
to each of the bottom labels.
I'm guessing either bottom label may wrap to multiple lines, so set each one to Number of Lines: 0
The layout:
the result:
How to wrap text UILabel Xcode with Storyboard settings
You need to add leading
and trailing
constraint to your label
Or you can add a width constraint relative to the superview width
Multiline text label not wrapping in Swift
You need to constrain its width, either through it's anchors or explicitly giving it a width.
Word wrap not working in UILabel
Try this. It should shrink the font just enough to fit the longest word on a line. If you see a better way let me know as I would love to improve this.I am sure I could adapt it to work in IB.
import UIKit
extension UILabel{
func adjustedFont()->UIFont {
let attributes: [NSAttributedStringKey: Any] = [.font: font]
let attributedString = NSAttributedString(string: text ?? "", attributes: attributes)
let drawingContext = NSStringDrawingContext()
drawingContext.minimumScaleFactor = minimumScaleFactor
attributedString.boundingRect(with: bounds.integral.size,
options: .usesLineFragmentOrigin,
context: drawingContext)
let fontSize = font.pointSize * drawingContext.actualScaleFactor
return font.withSize(fontSize)
}
func fitMaxWord(){
layoutIfNeeded()
let scaledFont = self.adjustedFont()
let currentFont = scaledFont
if let txt = text,
let maxString = txt.components(separatedBy: " ").max(by: {$1.count > $0.count})?.replacingOccurrences(of: "\n", with: ""){
let maxFontSize: CGFloat = currentFont.pointSize
let minFontSize: CGFloat = 5.0
var q = maxFontSize
var p = minFontSize
let height = currentFont.lineHeight
let constraintSize = CGSize(width: .greatestFiniteMagnitude, height: height)
var sizedFont = currentFont
while(p <= q){
let currentSize = (p + q) / CGFloat(2)
sizedFont = currentFont.withSize( CGFloat(currentSize) )
let text = NSMutableAttributedString(string:maxString, attributes:[NSAttributedStringKey.font:sizedFont])
let textRect = text.boundingRect(with: constraintSize, options: [.usesLineFragmentOrigin], context: nil).integral
let labelSize = textRect.width
//1 is a fudge factor
if labelSize == ceil(self.bounds.width - 1){
break
}else if labelSize > ceil(self.bounds.width - 1){
q = currentSize - 0.1
}else{
p = currentSize + 0.1
}
}
if sizedFont.pointSize < currentFont.pointSize{
self.font = sizedFont
}
}
}
}
Minimum example:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//we could test longer text
//
let text = "CHULALONGKORN UNIVERSITY Plus a lot of additional text to make sure it still does not clip a word"
let testLabel = UILabel(frame: .zero)
//testLabel.text = "CHULALONGKORN UNIVERSITY"
testLabel.text = text
testLabel.numberOfLines = 0
testLabel.textAlignment = .center
testLabel.font = UIFont.systemFont(ofSize: 45)
testLabel.adjustsFontSizeToFitWidth = true //unneeded in this instance but lets set it
testLabel.minimumScaleFactor = 0.3
self.view.addSubview(testLabel)
testLabel.translatesAutoresizingMaskIntoConstraints = false
testLabel.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 20).isActive = true
testLabel.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -20).isActive = true
testLabel.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50).isActive = true
self.view.layoutIfNeeded()
testLabel.fitMaxWord()
}
}
This should work in most circumstances. I tested with your text and more text. You can see both in the example above.
UILabel text doesn't word wrap
Just found the problem, my numberOfLines
was still at 1. After setting it to 0 it works fine.
UILabel not wrapping reliably
The key to getting it to work correctly was to ask the view to reset the layout after the constraints had been applied and all the text had been set. I merely added these lines to my custom UITableViewCell
after I had set the data that it needed:
//set data
//set constraints
...
contentView.setNeedsLayout()
contentView.layoutIfNeeded()
}
I realized this was the solution because the view kept reporting their initial frame sizes instead of sizes after being affected by their constraints. For some reason, all the other views looked correct but not the UILabels
.
I found the solution in the answer posted here: https://stackoverflow.com/a/13542580/1637033
UILabel not wrapping after the text is changed
When you change the text in a label in a table view cell, the table view does not automatically re-calculate cell sizes.
To do so, you either reload the data - as you've seen - or, execute these two lines:
tableView.beginUpdates()
tableView.endUpdates()
If you are updating the text in the label from inside your cell class, you'' want to use a delegate / protocol pattern to tell the table view controller to execute those two lines.
Related Topics
Wkwebview Does Not Load Links to Pdfs
Swift Sphere Combine Star Data
How to Transpose an Array More Swiftly
Include Swiftui Views in Existing Uikit Application
Generating Random Numbers With Swift
Swiftui - Is There a Popviewcontroller Equivalent in Swiftui
What's the Difference Between Using Aranchor to Insert a Node and Directly Insert a Node
Generic Swift 4 Enum With Void Associated Type
Ios13 Navigation Bar Large Titles Not Covering Status Bar
How to Configure Contextmenu Buttons For Delete and Disabled in Swiftui
Extension May Not Contain Stored Property But Why Is Static Allowed
Is There a Method to Blur a Background in Swiftui
Re-Initialize a Lazy Initialized Variable in Swift
Returning a Value from a Function with Alamofire and Swiftyjson
Adding Swift File to New View Controller in Xcode? (Easy)
Property Observers Willset and Didset; Property Getters and Setters