swift ——多行文字前面内容省略

首先来说一说ios中的 lineBreakMode
lineBreakMode : 设置文字过长时的显示截断样式

可选值如下

  • byWordWrapping : 以单词为单位换行,以单词为单位截断。
  • byCharWrapping :以字符为单位换行,以字符为单位截断。
  • byClipping : 以单词为单位换行,以字符为单位截断。
  • byTruncatingHead : 以单词为单位换行, 如果是单行,则开始部分有省略号。如果是多行,则中间有省略号。
  • byTruncatingTail : 以单词为单位换行, 无论是单行还是多行,都是末尾有省略号。
  • byTruncatingMiddle : 以单词为单位换行, 无论是单行还是多行,都是中间有省略号。

三种省略方式如下


byTruncatingHead为头部截断,但是文字为多行时省略的是中间内容而不是头部内容,下面我们就来实现多行文字,文字超过设定行数后省略头部的功能

首先根据容器的宽度和字体的大小计将文本分割成多行

Swift 复制代码
func splitTextIntoLines(text: String, width: CGFloat, font: UIFont) -> [String] {
        let textBox = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude) // 设定文本框的宽和最大高
        let attributes: [NSAttributedString.Key: Any] = [.font: font] // 定义属性字典,为了设置字体

        // 创建NSTextStorage,并应用上面定义的属性
        let textStorage = NSTextStorage(string: text, attributes: attributes)
        let layoutManager = NSLayoutManager() // 创建布局管理器
        textStorage.addLayoutManager(layoutManager) // 将布局管理器添加到文本存储中

        // 创建NSTextContainer,设置其大小为之前定义的textBox
        let textContainer = NSTextContainer(size: textBox)
        textContainer.lineFragmentPadding = 0 // 设置行片段(padding)的填充为0
        textContainer.maximumNumberOfLines = 0 // 表示没有最大行数限制
        textContainer.lineBreakMode = .byWordWrapping // 设置折行模式为按单词换行
        layoutManager.addTextContainer(textContainer) // 将文本容器添加到布局管理器中

        var lines: [String] = [] // 创建一个数组用于存储分割后的每一行文本
        
        var range = NSRange(location: 0, length: 0) // 初始化一个NSRange对象

        // 使用enumerateLineFragments方法获取每一行的文本
        layoutManager.enumerateLineFragments(forGlyphRange: NSRange(location: 0, length: layoutManager.numberOfGlyphs)) { _, usedRect, _, glyphRange, _ in
            
            // 将NSRange类型的glyphRange转换为Range<String.Index>类型,这样可以安全地使用Swift的String索引
            let characterRange = Range(glyphRange, in: text)
            if let characterRange = characterRange {
                let line = String(text[characterRange]) // 从原始文本中获取行文本并添加到lines数组
                lines.append(line)
            }
            
            range = NSUnionRange(range, glyphRange) // 更新处理过的字符范围
        }
        
        return lines // 返回包含所有行的数组
    }

获取想要的行数文字

Swift 复制代码
/**
           text:字符串
            font:字号
            limit:显示行数
     */
    func truncat(text:String,width: CGFloat, font: UIFont,limit:Int) -> String{
        let allLines =  splitTextIntoLines(text: text, width: width, font: font)
        let lines = allLines.suffix(limit)
        var origString = ""
        for (index,line) in lines.enumerated() {

            origString += line
        }

        print(origString)
        return "...\(origString)"
    }

效果如下

要注意的是 truncat传入的width和font要与文字容器的宽度和文字字体一致

相关推荐
Ajiang28247353045 分钟前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
幽兰的天空10 分钟前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
Theodore_10223 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
----云烟----5 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024065 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
开心工作室_kaic6 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it6 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
武子康6 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神6 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
宅小海7 小时前
scala String
大数据·开发语言·scala