问题
I have 3 UILabels
and I want to set same (the smallest one from all of 3 possibilities) font for all of them. What is the problem? I don't know how to check the current font - each of UILabels
use Autoshrink
with minimal font scale and lines amount equaled to 0. The text of UILabels is set in ViewDidLoad()
method (there are many combinations of possible label texts).
I tried to get the current font size with UILabel.font.pointSize
property (called in viewDidAppear()
method) and than compare all of them. The problem is that that UILabel.font.pointSize
returns not current value of UILabel text font size (after Autoshrink
has been done) but the value that is set in storyboard.
I'm totally out of ideas so thanks for the help!
Greetings, John
回答1:
This is one way to get the current size of the UILabel pointsize although I know of more ways if this does not work. This is the cleanest and fastest. See example and extension included.
import UIKit
class ViewController: UIViewController {
lazy var label1 : UILabel = {
let lbl = UILabel(frame: CGRect(x: 20, y: 80, width: self.view.bounds.width - 40, height: 40))
lbl.text = "This is some large text to make it fit to size with a big font size"
lbl.font = UIFont.systemFont(ofSize: 50, weight: .bold)
lbl.textColor = .black
lbl.minimumScaleFactor = 0.01
lbl.adjustsFontSizeToFitWidth = true
lbl.numberOfLines = 0
return lbl
}()
lazy var label2 : UILabel = {
let lbl = UILabel(frame: CGRect(x: 20, y: label1.frame.maxY + 5, width: self.view.bounds.width - 40, height: 40))
lbl.text = "This is one line"
lbl.font = UIFont.systemFont(ofSize: 20, weight: .bold)
lbl.textColor = .black
lbl.minimumScaleFactor = 0.01
lbl.adjustsFontSizeToFitWidth = true
lbl.numberOfLines = 0
return lbl
}()
lazy var label3 : UILabel = {
let lbl = UILabel(frame: CGRect(x: 20, y: label2.frame.maxY + 10, width: self.view.bounds.width - 40, height: 80))
lbl.text = "This is some large text to make it fit to size with a big font size"
lbl.font = UIFont.systemFont(ofSize: 100, weight: .bold)
lbl.textColor = .black
lbl.minimumScaleFactor = 0.01
lbl.adjustsFontSizeToFitWidth = true
lbl.numberOfLines = 0
return lbl
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view.addSubview(label1)
self.view.addSubview(label2)
self.view.addSubview(label3)
var minSize : CGFloat = .greatestFiniteMagnitude
for sub in self.view.subviews{
if let lbl = sub as? UILabel{
//get the size
let font = lbl.adjustedFont()
print("the size is \(font.pointSize)")
minSize = min(font.pointSize,minSize)
}
}
print("the minimum for all fonts is \(minSize)")
print("i am going to delay for 3 seconds and then reset all the labels to the minimum size :)")
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3.0) {
for sub in self.view.subviews{
if let lbl = sub as? UILabel{
lbl.font = lbl.font.withSize(minSize)
}
}
}
}
}
extension UILabel{
func adjustedFont()->UIFont {
guard let txt = text else {
return self.font
}
let attributes: [NSAttributedString.Key: Any] = [.font: self.font]
let attributedString = NSAttributedString(string: txt, attributes: attributes)
let drawingContext = NSStringDrawingContext()
drawingContext.minimumScaleFactor = self.minimumScaleFactor
attributedString.boundingRect(with: bounds.size,
options: [.usesLineFragmentOrigin,.usesFontLeading],
context: drawingContext)
let fontSize = font.pointSize * drawingContext.actualScaleFactor
return font.withSize(CGFloat(floor(Double(fontSize))))
}
}
Example in Action
回答2:
What I've found is that inside viewDidLoad()
your constraints are not fully defined yet. You can try to do these calculations in another method for example viewWillAppear()
or any other that suits you and is executed after viewDidLoad()
.
回答3:
use this extention
extension String {
func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
return ceil(boundingBox.height)
}
}
get height
height = strDesc.height(withConstrainedWidth: UIScreen.main.bounds.size.width - 160, font: UIFont.systemFont(ofSize: 14.0))
来源:https://stackoverflow.com/questions/52929271/how-to-check-current-font-size-of-uilabel