Swift:UILabel超出宽度文字的截取

简介: Swift:UILabel超出宽度文字的截取

JKSwiftExtension,测试用例在 JKContentSizeViewController.swift 里面

需求:单行文字可缩放到一定比例,按照Char截取,超出截掉,不允许出现Char被截取一半的情况


image.png

一、常规的剪切方式 (lineBreakMode 设置文字过长时的显示格式)



  • 1.1、NSLineBreakMode枚举如下


public enum NSLineBreakMode : Int {
   //  以单词为显示单位显=示,后面部分省略不显示
   case byWordWrapping = 0 
   // 以字符为显示单位显示,后面部分省略不显示。
   case byCharWrapping = 1 
   // 剪切与文本宽度相同的内容长度,后半部分被删除。
   case byClipping = 2 
   // 前面部分文字以……方式省略,显示尾部文字内容
   case byTruncatingHead = 3 
   // 结尾部分的内容以……方式省略,显示头的文字内容
   case byTruncatingTail = 4 
   // 中间的内容以……方式省略,显示头尾的文字内容
   case byTruncatingMiddle = 5 
}
  • 使用如下:以 byWordWrapping 的形式剪切


let label = UILabel(frame: CGRect(x: 20, y: 20, width: 100, height: 19))
label.backgroundColor = .yellow
label.font = UIFont.systemFont(ofSize: 10)
label.textAlignment = .left
label.textColor = UIColor.brown
label.lineBreakMode = .byWordWrapping
return label


二、本次的需求实现



  • 2.1、需求:单行文字可缩放到一定比例,按照Char截取,超出截掉,不允许出现Char被截取一半的情况
  • 需求分析:可缩放一定比例按照Char截取不允许出现Char被截取一半的情况
  • 实现方式:先获取缩放后的字体大小,后获取指定宽度的第一行文字的内容
  • 2.2、具体的核心代码如下


public struct JKContentSize {}
public extension JKContentSize {
    // MARK: 2.1、行数和每行的内容
    /// 获取已知 width 的 label 的文本行数 & 每一行内容
    /// - Parameters:
    ///   - content: 文本的内容
    ///   - font: 字体
    ///   - width: 宽度
    ///   - height: 高度
    ///   - minimumScaleFactor: 缩放率
    /// - Returns: 文本行数 & 每一行内容
    static func linesCountAndLinesContent(content: String, font: UIFont, width: CGFloat, height: CGFloat, minimumScaleFactor: CGFloat = 1.0) -> (Int?, [String]?) {
        let lodFontName = font.fontName
        let fontSize = getFontSizeForLabel(content: content, minimumScaleFactor: minimumScaleFactor, font: font, width: width, height: height)
        let newFont = UIFont(name: lodFontName, size: fontSize) ?? UIFont.systemFont(ofSize: fontSize)
        let c_fn = newFont.fontName as CFString
        let fp = newFont.pointSize
        let c_f = CTFontCreateWithName(c_fn, fp, nil)
        let style = NSMutableParagraphStyle()
        style.lineBreakMode = .byCharWrapping
        let contentDict = [NSAttributedString.Key.paragraphStyle : style] as [NSAttributedString.Key : Any]
        let attr = NSMutableAttributedString(string: content)
        let range = NSRange(location: 0, length: attr.length)
        attr.addAttributes(contentDict, range: range)
        attr.addAttribute(NSAttributedString.Key.font, value: c_f, range: range)
        let frameSetter = CTFramesetterCreateWithAttributedString(attr as CFAttributedString)
        let path = CGMutablePath()
        /// 2.5 是经验误差值
        path.addRect(CGRect(x: 0, y: 0, width: width, height: height > (fp * 1.5) ? height : fp * 1.5))
        let framef = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil)
        let lines = CTFrameGetLines(framef) as NSArray
        var lineArr = [String]()
        for line in lines {
            let lineRange = CTLineGetStringRange(line as! CTLine)
            let lineString = content.jk.sub(start: lineRange.location, length: lineRange.length)
            lineArr.append(lineString as String)
        }
        return (lineArr.count, lineArr)
    }
    // MARK: 获取字体的大小
    /// 获取字体的大小
    /// - Returns: 字体的大小
    private static func getFontSizeForLabel(content: String, minimumScaleFactor: CGFloat, font: UIFont, width: CGFloat, height: CGFloat) -> CGFloat {
        let text: NSMutableAttributedString = NSMutableAttributedString(attributedString: NSAttributedString(string: content))
        text.setAttributes([NSAttributedString.Key.font: font as Any], range: NSMakeRange(0, text.length))
        let context: NSStringDrawingContext = NSStringDrawingContext()
        context.minimumScaleFactor = minimumScaleFactor
        text.boundingRect(with: CGSize(width: width, height: height), options: NSStringDrawingOptions.usesLineFragmentOrigin, context: context)
        let adjustedFontSize: CGFloat = font.pointSize * context.actualScaleFactor
        return adjustedFontSize
    }
}


目录
相关文章
|
Swift
Swift之设置UItextField的占位文字颜色颜色
Swift之设置UItextField的占位文字颜色颜色
266 0
Swift之设置UItextField的占位文字颜色颜色
|
Swift
Swift - 如何让UIView,UILabel和UIImageView之间类型互相转化
Swift - 如何让UIView,UILabel和UIImageView之间类型互相转化
146 0
|
测试技术 Swift
Swift:UILabel+Extension
Swift:UILabel+Extension
465 0
|
iOS开发
swift4.0 根据文字计算带emoji的文字高度
这是一个基本的功能,实现的方法自然也很多了,仁者见仁,智者见智,若觉得我的实现不够好,欢迎指正。 效果图: 高度截图.gif 文字高度截图.
1151 0
|
iOS开发 Swift
swift 学习笔记之在UILabel中显示多行文字
原文链接:http://www.douban.com/group/topic/70990429/ 在Xcode中使用UILabel控件显示单行文本非常简单便捷,可一旦遇到需要使用多行文本时则显得稍显无力。
1496 0
Swift: 打造滑动解锁文字动画
原文:Swift: 打造滑动解锁文字动画 最近木事,找出来玩了玩facebook的paper。到处都是那个"slide to unlock your phone"的效果啊。忽闪忽闪的小有点炫酷的感觉。于是准备研究一下。
924 0
|
5月前
|
Unix 调度 Swift
苹果iOS新手开发之Swift 中获取时间戳有哪些方式?
在Swift中获取时间戳有四种常见方式:1) 使用`Date`对象获取秒级或毫秒级时间戳;2) 通过`CFAbsoluteTimeGetCurrent`获取Core Foundation的秒数,需转换为Unix时间戳;3) 使用`DispatchTime.now()`获取纳秒级精度的调度时间点;4) `ProcessInfo`提供设备启动后的秒数,不表示绝对时间。不同方法适用于不同的精度和场景需求。
171 3