I create a UILabel like this, but nothing happens, the text does not increase.
my code:
firstLabel = UILabel()
firstLabel.text = "Выберите 2 лица"
firstLabel.textColor = UIColor(alpha: 1, red: 64, green: 156, blue: 255)
firstLabel.textAlignment = .center
firstLabel.numberOfLines = 1
firstLabel.minimumScaleFactor = 0.1
firstLabel.adjustsFontSizeToFitWidth = true
firstLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(firstLabel)
firstLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 3 * widthView/8).isActive = true
firstLabel.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true
firstLabel.widthAnchor.constraint(equalToConstant: safeWidthView - 40).isActive = true
adjustsFontSizeToFitWidth will not increase the font size to fill the remaining space in label if the label has bigger width than the actual content size, it is intended to only shrink the font size to appropriate value to accommodate text if text is bigger than than label's bounding rectangle
Quoting apple
Normally, the label draws the text with the font you specify in the
font property. If this property is true, and the text in the text
property exceeds the label’s bounding rectangle, the label reduces the
font size until the text fits or it has scaled the font down to the
minimum font size. The default value for this property is false. If
you change it to true, be sure that you also set an appropriate
minimum font scale by modifying the minimumScaleFactor property. This
autoshrinking behavior is only intended for use with a single-line
label.
Link: https://developer.apple.com/documentation/uikit/uilabel/1620546-adjustsfontsizetofitwidth
Related
I have a UILabel inside a UITableViewCell that I want to dynamically adjust its font and size based on content to always maintain the largest font that it can support without truncating. I am most of the way there using adjustsFontSizeToFitWidth, but the label has extra vertical space that it does not need.
In this screenshot running on the iPhone SE simulator, the label correctly scaled the font down from 55 to fit, but there is this extra space at the top of the label. I want that space to go away!
Here is my label code:
private lazy var label: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 55, weight: .ultraLight)
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.25
label.backgroundColor = .purple
return label
}()
Here is my layout code:
self.addSubview(self.labelsContainerView)
self.labelsContainerView.snp.makeConstraints { (make) in
make.leading.equalTo(leftView.snp.trailing).offset(20)
make.trailing.equalTo(rightView.snp.leading).offset(-20)
make.top.bottom.equalToSuperview()
}
self.labelsContainerView.addSubview(self.middleLabel)
self.middleLabel.snp.makeConstraints { (make) in
make.leading.trailing.centerY.equalToSuperview()
}
self.labelsContainerView.addSubview(self.topLabel)
self.topLabel.snp.makeConstraints { (make) in
make.leading.equalToSuperview()
make.bottom.equalTo(self.middleLabel.snp.top)
make.top.equalToSuperview().offset(8)
}
self.labelsContainerView.addSubview(self.bottomLabel)
self.bottomLabel.snp.makeConstraints { (make) in
make.leading.equalToSuperview()
make.top.equalTo(self.middleLabel.snp.bottom)
make.bottom.equalToSuperview().offset(-8)
}
In short, I have a UIView pinned to the top and bottom of my UITableViewCell. Inside that view, I have 3 labels: top, middle, and bottom. The labels are pinned top-to-bottom.
I want middleLabel to always be the largest size it can be to satisfy layout and use the largest font that will fit inside that size without truncating. It seems almost like the intrinsic content size isn't being updated when the label's font changes. I have tried all kinds of calls to setNeedsLayout() and layoutIfNeeded() but they never helped.
It will take some extra work to get the label's Height to change, but if you only need the text vertically centered, add this to your label configuration:
label.baselineAdjustment = .alignCenters
Here's the difference... top uses default .alignBaselines bottom uses .alignCenters:
I have a label that resizes it's
label.adjustsFontForContentSizeCategory = true
label.adjustsFontSizeToFitWidth = true
If I set short text, it stays in the center. But if I put long text, it goes down. What do I need to do?
Label constrained to be in X and Y centers of the view.
Short text:
Long text:
Add the following code:
label.adjustsFontForContentSizeCategory = true
label.adjustsFontSizeToFitWidth = true
label.label.minimumScaleFactor = 0.4
label.numberOfLines = 1
Set UIlabel Top, hight, >= width and horizontally center constraint see the following image and get the expected output as you want.
Note: Keep the number of line 1 as it is.
Short text output:
Long text output:
Set the following constraint
Top, height, width
Horizontally center constraint
Width is >=
In iOS 8, I have a vanilla UITextView that clips the top of the 1st line when a lineHeightMultiple is applied to it's NSMutableParagraphStyle, see image below:
It appears as though lineHeightMultiple affects the 1st line of text in addition to subsequent lines.
Setting clipsToBounds = false on the UITextView will at least enable the clipped part to show, but you can see from the image below that now the top part of the text is obviously above it's frame:
I can fix this by just setting the top constraint on the offending UITextView to compensate for clipsToBounds = false but that feels like a hack to me.
I have also tried using a WKWebView for the offending text, and just setting the css line-height property, and that works just fine. There must simply be something I am missing when it comes to UITextView though.
Additionally, setting lineSpacing on the paragraph style to less than 0 has no affect, per the docs:
The distance in points between the bottom of one line fragment
and the top of the next.
**This value is always nonnegative.**
This value is included in the line fragment heights in the
layout manager.
I have also tried setting the contentInset of the UITextView as well as using a system font, both had not affect.
My sample code for this setup follows:
let text = "THIS IS A MULTILINE RUN OF TEXT"
let font = UIFont(name: "MyFontName", size: 31.0)!
// let font = UIFont.systemFontOfSize(31.0)
let paragraph = NSMutableParagraphStyle()
paragraph.lineHeightMultiple = 0.75
paragraph.alignment = NSTextAlignment.Center
let attributes = [
NSParagraphStyleAttributeName: paragraph,
NSFontAttributeName: font
]
titleView.attributedText = NSAttributedString(string: text, attributes: attributes)
// titleView.contentInset = UIEdgeInsets(top: 50.0, left: 0.0, bottom: 0.0, right: 0.0)
titleView.clipsToBounds = false
Has anyone encountered this and overcome or is the top constraint hack the only way to go?
I had the same issue.
I compensated it using NSBaselineOffsetAttributeName.
You should use:
let attributes = [
NSParagraphStyleAttributeName: paragraph,
NSFontAttributeName: font,
NSBaselineOffsetAttributeName: -5
]
You will have to also set a lower paragraph.lineHeightMultiple.
A little tricky, but it works.
Cooliopas is right, but I ended up using this in a label extension and needed something more suited for the many different sizes of text throughout my app. I found that the baseline adjustment to keep the text vertically centered was 10% of the height of the text.
let attrString = NSMutableAttributedString(string: newText)
let style = NSMutableParagraphStyle()
style.alignment = self.textAlignment
style.lineSpacing = 1.0
style.lineHeightMultiple = 0.75
var baselineOffset : CGFloat = -5 //-5 is a default for this in case there is no attributedText size to reference
if let size = self.attributedText?.size(){
baselineOffset = size.height * -0.1
} else {
NSLog("attributedText = nil, setting lineHeightMultiple to -5 as a default for ", newText)
}
attrString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSMakeRange(0, attrString.length))
attrString.addAttribute(NSBaselineOffsetAttributeName, value: baselineOffset, range: NSMakeRange(0, attrString.length))
self.clipsToBounds = false
self.attributedText = attrString
Alternative approach - use a stack view with two labels, and set the stack view spacing to the top label's font's descender.
I have a multi line label with a set size (300 x 300).
I want to adjust the label's font size programmatically according to how long the label's text is and how big the label is.
Here are 2 examples of the same sized labels with different length text strings
Refer to NSString.boundingRectWithSize:options:attributes:. Here you need to decrement the font size stepwise until the string will fit into the original frame.
var paragraph = NSMutableParagraphStyle()
let layout = [NSFontAttributeName:NSFont.systemFontOfSize(0), NSParagraphStyleAttributeName: paragraph, ]
paragraph.lineBreakMode = NSLineBreakMode.ByWordWrapping
var a = NSString(string: "My long text")
let rect = NSMakeSize(30, 20)
let bb = a.boundingRectWithSize(rect, options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: layout)
Place the above in Playground and modify rect and the font to see what happens.
I know the Question is old but....
Just use the option AutoShrink and set the minimum font size/scale in the Attributes Inspector, it will scale the font as large as possible to fit the size of the label.
I've created a Label with the following code :
func setupValueLabel() {
valueLabel.numberOfLines = 1
valueLabel.font = UIFont(name: "Avenir-Black", size: 50)
valueLabel.adjustsFontSizeToFitWidth = true
valueLabel.clipsToBounds = true
valueLabel.backgroundColor = UIColor.greenColor()
valueLabel.textColor = valuesColor
valueLabel.textAlignment = NSTextAlignment.Center
}
I don't really understand why but the label is not vertically centered :
Do I have to do anything specific so it can be centered ?
The problem is that font size is shrunk by adjustsFontSizeToFitWidth = true, but it does not adjust the lineHeight automatically. It remains to be for original font size that is 50.
By default, the text is aligned to its baseline. you can adjust it with baselineAdjustment property.
In your case, you should set it to UIBaselineAdjustment.alignCenters.
valueLabel.baselineAdjustment = .alignCenters
Thanks to #rintaro, it works finally.
One more thing for my case, it didn't work because I was setting ByWordWrapping. I had to set lineBreakMode as ByClipping.