iOS开发之UILabel末尾增加展开折叠—Swift

前言

针对超过指定行数显示展开,点击后显示全文,简单封装了一个控件,在此抛砖引玉供大家参考。

特性

  1. 支持富文本
  2. 支持内边距
  3. 支持AutoLayout

原理

使用CoreText切割字符串后,计算截断符的宽度,按照宽度重新生成新的字符串。这里核心在于如何保障新的字符串不会超出设置的行数。核心代码参考如下:

func reload() {
    guard let attributedText = attributedText?.addAttributes({ $0.font(textLabel.font) }) else { return }
    guard Thread.isMainThread else { return DispatchQueue.main.async { self.reload() } }
    setNeedsLayout()
    layoutIfNeeded()
    let width = textLabel.bounds.width
    let lines = attributedText.lines(width)
    if numberOfLines > 0,
       lines.count >= numberOfLines {
        let additionalAttributedText = isOpen ? truncationToken.close : truncationToken.open
        let length = lines.prefix(numberOfLines).reduce(0, { $0 + CTLineGetStringRange($1).length })
        textLabel.attributedText = additionalAttributedText
        let truncationTokenWidth = textLabel.sizeThatFits(.zero).width
        let maxLength = isOpen ? attributedText.length : min(CTLineGetStringIndexForPosition(lines[numberOfLines - 1], CGPoint(x: width - truncationTokenWidth, y: 0)), length) - 1
        displayAttributedText = {
           let attributedText = NSMutableAttributedString(attributedString: attributedText.attributedSubstring(from: NSRange(location: 0, length: maxLength)))
            attributedText.append(additionalAttributedText)
            return attributedText
        }()
    }
    textLabel.attributedText = displayAttributedText
}

效果图

效果图

Demo

核心代码已经贴出,完整代码请查看----->>>GitHub,如果对你有所帮助,欢迎Star。

你可能感兴趣的:(iOS开发之UILabel末尾增加展开折叠—Swift)