//
// Label+Getheight.swift
// LabelH
//
// Created by 李鹏跃 on 2018/6/25.
// Copyright © 2018年 李鹏跃. All rights reserved.
//
import UIKit
extension UILabel {
enum GetSizeType_ENUM: Int {
case text = 0
case attributeString
}
/// 自动计算了label 的宽度,在此之前,需要有label的宽度约束
///
/// - Returns:
/// 获取label的高度,
///
/// - Parameters:
/// - type: 计算text 还是attributeText,如果不传则(如果有text的话,优先计算attributeText的height,没有attributeText则计算text的height,如果两个都没有值则返回0)
/// - width: width的最大值。如果不传则(自动计算了label 的width,在此之前,需要有label的width约束)
/// - Returns: 文本实际高度的最大值
func getLabelHeight(type: GetSizeType_ENUM? = nil, width: CGFloat? = nil) -> CGFloat {
var w: CGFloat = width ?? -1
var h: CGFloat = CGFloat.greatestFiniteMagnitude
if w <= 0 {
if frame.width == 0 {
layoutIfNeeded()
}
guard frame.width != 0 else {
print("🌶🌶🌶: 计算label的height失败,因为其width为0")
return 0
}
w = frame.width
}
if let attributedText = attributedText, let type = type, type == .attributeString{
h = attributedText.getSize(width: w, height: h).height
}else if let text = text {
h = text.getLableHeigh(font: font, width: w)
}else {
print("label没有text,或者attribute")
}
return h
}
/// 获取label的widht,
///
/// - Parameters:
/// - type: 计算text 还是attributeText,如果不传则(如果有text的话,优先计算attributeText的width,没有attributeText则计算text的width,如果两个都没有值则返回0)
/// - height: 高度的最大值。如果不传则(自动计算了label 的height,在此之前,需要有label的height约束)
/// - Returns: 文本的宽度最大值
func getLabelWidth(type: GetSizeType_ENUM? = nil, height: CGFloat? = nil) -> CGFloat {
var w: CGFloat = CGFloat.greatestFiniteMagnitude
var h: CGFloat = height ?? -1
if h <= 0 {
if frame.width == 0 {
layoutIfNeeded()
}
guard frame.height != 0 else {
print("🌶🌶🌶: 计算label的width失败,因为其height为0")
return 0
}
h = frame.height
}
if let attributedText = attributedText, let type = type, type == .attributeString{
w = attributedText.getSize(width: w, height: h).width
}else if let text = text {
w = text.getLableWidth(font: font, height: h)
}else {
print("label没有text,或者attribute")
}
return w + 1
}
/// 限制最大汉字数
///
/// - Parameters:
/// - maxCount: 最多显示多少个字
/// - Returns: label的宽度
func getLabelWidth(type: GetSizeType_ENUM? = nil, height: CGFloat? = nil, maxCount: Int64) -> CGFloat {
var str = "哈"
for _ in 0 ..< maxCount {
str += "哈"
}
let text = self.text
let attributedText = self.attributedText
let textW = getLabelWidth(type: type, height: height)
self.text = str
let strW = getLabelWidth(height: height)
self.text = text
self.attributedText = attributedText
return strW < textW ? strW : textW
}
}
// MARK: - get NSAttributedString height
extension NSAttributedString {
/// 根据给定的范围计算宽高,如果计算宽度,则请把宽度设置为最大,计算高度则设置高度为最大
///
/// - Parameters:
/// - width: 宽度的最大值
/// - height: 高度的最大值
/// - Returns: 文本的实际size
func getSize(width: CGFloat,height: CGFloat) -> CGSize {
let attributed = self
let ctFramesetter = CTFramesetterCreateWithAttributedString(attributed)
let rect = CGRect.init(x: 0, y: 0, width: width, height: height)
let framesetter = CTFramesetterCreateWithAttributedString(attributed)
let size = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRange.init(location: 0, length: attributed.length), nil, rect.size, nil)
return CGSize.init(width: size.width + 1, height: size.height + 1)
}
func getImageRunFrame(run: CTRun, lineOringinPoint: CGPoint, offsetX: CGFloat) -> CGRect {
/// 计算位置 大小
var runBounds = CGRect.zero
var h: CGFloat = 0
var w: CGFloat = 0
var x: CGFloat = 0
var y: CGFloat = 0
var asecnt: CGFloat = 0
var descent: CGFloat = 0
var leading: CGFloat = 0
let cfRange = CFRange.init(location: 0, length: 0)
w = CGFloat(CTRunGetTypographicBounds(run, cfRange, &asecnt, &descent, &leading))
h = asecnt + descent + leading
/// 获取具体的文字距离这行原点的距离 || 算尺寸用的
x = offsetX + lineOringinPoint.x
/// y
y = lineOringinPoint.y - descent
runBounds = CGRect.init(x: x, y: y, width: w, height: h)
return runBounds
}
}
// MARK: - get String height
extension String {
func getLableHeigh(font:UIFont,width:CGFloat) -> CGFloat {
let size = CGSize.init(width: width, height: CGFloat(MAXFLOAT))
// let dic = [NSAttributedStringKey.font:font] // swift 4.0
let dic = [NSAttributedStringKey.font:font] // swift 3.0
let strSize = self.boundingRect(with: size, options: [.usesLineFragmentOrigin], attributes: dic, context:nil).size
return ceil(strSize.height) + 1
}
///获取字符串的宽度
func getLableWidth(font:UIFont,height:CGFloat) -> CGFloat {
let size = CGSize.init(width: CGFloat(MAXFLOAT), height: height)
// let dic = [NSAttributedStringKey.font:font] // swift 4.0
let dic = [NSAttributedStringKey.font:font] // swift 3.0
let cString = self.cString(using: String.Encoding.utf8)
let str = String.init(cString: cString!, encoding: String.Encoding.utf8)
let strSize = str?.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: dic, context:nil).size
return strSize?.width ?? 0
}
}
网友评论