Preface
Many syntaxes are not familiar with swift. This article mainly introduces to you about using Swift to calculate text size. It is shared for your reference and learning. I won’t say much below. Let’s take a look at the detailed introduction.
Before iOS 11, the size of the string is used to limit the width and height calculationUILabel's textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect
Method, I didn't consider thread safety issues at that time (low exploded), and Xcode didn't prompt it. I used several versions, but fortunately I've never had any problems.
Post the method (I won't explain why I chose this method at that time):
func textSize(font: UIFont, constrainedSize: CGSize, lineSpacing: CGFloat?, lines: Int) -> CGSize { if || lines < 0 { return } let attributedString = NSMutableAttributedString(string: self) let range = NSRange(location: 0, length: ) ([NSFontAttributeName: font], range: range) if lineSpacing != nil { let paragraphStyle = NSMutableParagraphStyle() = .byTruncatingTail = lineSpacing! (NSParagraphStyleAttributeName, value: paragraphStyle, range: range) } let calculatedLabel = UILabel() = font = attributedString = lines let rect = (forBounds: CGRect(x: 0, y: 0, width: , height: ), limitedToNumberOfLines: lines) return }
Recently upgraded Xcode 9, warning me when runninglet calculatedLabel = UILabel()
Only when the main thread is executed, will you realize the seriousness of the problem and make changes immediately:
extension String { func boundingRect(with constrainedSize: CGSize, font: UIFont, lineSpacing: CGFloat? = nil) -> CGSize { let attritube = NSMutableAttributedString(string: self) let range = NSRange(location: 0, length: ) ([: font], range: range) if lineSpacing != nil { let paragraphStyle = NSMutableParagraphStyle() = lineSpacing! (, value: paragraphStyle, range: range) } let rect = (with: constrainedSize, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil) var size = if let currentLineSpacing = lineSpacing { // Subtract the height of the text by font height to be less than or equal to the line spacing, and it is determined that there is only 1 line at present let spacing = - if spacing <= currentLineSpacing && spacing > 0 { size = CGSize(width: , height: ) } } return size } func boundingRect(with constrainedSize: CGSize, font: UIFont, lineSpacing: CGFloat? = nil, lines: Int) -> CGSize { if lines < 0 { return .zero } let size = boundingRect(with: constrainedSize, font: font, lineSpacing: lineSpacing) if lines == 0 { return size } let currentLineSpacing = (lineSpacing == nil) ? ( - ) : lineSpacing! let maximumHeight = *CGFloat(lines) + currentLineSpacing*CGFloat(lines - 1) if >= maximumHeight { return CGSize(width: , height: maximumHeight) } return size } }
Parameter explanation
- constrainedSize: limited size
- font:Font
- lineSpacing: default is nil, using the system's default line spacing
- lines: limit number of rows
Note:The code version is Swift 4.0
The above two methods replace the names: method 1 and method 2 respectively.
Method 1: Limit width and height, set the line spacing, and accurately calculate
Method 2: There is more limiting number of rows than Method 1.
Extension method using UILabel:
extension UILabel { // Reason for setting `numberOfLines = 0`: // Use the method `func boundingRect(with constrainedSize: CGSize, font: UIFont, lineSpacing: CGFloat? = nil, lines: Int) -> CGSize` can solve the problem of not displaying the limiting number of rows normally; // If the limit number of rows (the premise greater than 0) is set for the label, use the above calculation method (with line spacing), and at the same time, the actual number of rows of the string is greater than the limit number of rows, the height at this time will make the label unable to display normally. func setText(with normalString: String, lineSpacing: CGFloat?, frame: CGRect) { = frame = 0 let paragraphStyle = NSMutableParagraphStyle() = .byTruncatingTail if lineSpacing != nil { if ( - ) <= lineSpacing! { = 0 } else { = lineSpacing! } } let attributedString = NSMutableAttributedString(string: normalString) let range = NSRange(location: 0, length: ) ([: font], range: range) (, value: paragraphStyle, range: range) = attributedString } }
Thanks to the hamster here:iOS line spacing guideand/zhengwenming/WeChat
Summarize
The above is the entire content of this article. I hope that the content of this article has a certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support.