当前位置: > > > Swift - 判断UILabel文字是否被截断(是否有多余文字被省略)

Swift - 判断UILabel文字是否被截断(是否有多余文字被省略)

    当 UILabel 文本标签里的内容超出显示区域时,多余的部分会自动被截断,并在末尾处显示省略号(不管是单行显示、还是多行显示):
          

    有时我们需要知道 label 中的文字是否溢出。比如点击被截断的文字时,弹出一个显示完整内容的消息框。下面通过样例演示如何判断文字是否被截断。

1,扩展 UILabel

    为方便使用首先对 UILabel 进行扩展,增加一个 isTruncated 属性来表示当前内容是否被截断。其内部逻辑就是比较下面两种行数的大小:
  • 所有文字如果要完全显示的话需要的行数
  • 实际能显示的行数
extension UILabel {
    //判断文本标签的内容是否被截断
    var isTruncated: Bool {
        guard let labelText = text else {
            return false
        }
        
        //计算理论上显示所有文字需要的尺寸
        let rect = CGSize(width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude)
        let labelTextSize = (labelText as NSString)
            .boundingRect(with: rect, options: .usesLineFragmentOrigin,
                          attributes: [NSAttributedStringKey.font: self.font], context: nil)
        
        //计算理论上需要的行数
        let labelTextLines = Int(ceil(CGFloat(labelTextSize.height) / self.font.lineHeight))
        
        //实际可显示的行数
        var labelShowLines = Int(floor(CGFloat(bounds.size.height) / self.font.lineHeight))
        if self.numberOfLines != 0 {
            labelShowLines = min(labelShowLines, self.numberOfLines)
        }
        
        //比较两个行数来判断是否需要截断
        return labelTextLines > labelShowLines
    }
}

2,使用样例

 (1)下面是对单行文本标签的判断:
import UIKit

class ViewController: UIViewController {
    
    var label:UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        label = UILabel(frame:CGRect(x:10, y:60, width:150, height:100))
        label.text = "hangge.com 欢迎访问,hangge.com 欢迎访问"
        self.view.addSubview(label)
    }
    
    @IBAction func checkTruncate(_ sender: Any) {
        let alertController = UIAlertController(title: "是否被截断",
                                                message: "\(label.isTruncated)",
                                                preferredStyle: .alert)
        let cancelAction = UIAlertAction(title: "确定", style: .cancel, handler: nil)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)
    }
}

(2)对于多行文本标签的判断也是支持的:
import UIKit

class ViewController: UIViewController {
    
    var label:UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        label = UILabel(frame:CGRect(x:10, y:60, width:150, height:100))
        label.text = "hangge.com 欢迎访问,hangge.com 欢迎访问"
        label.numberOfLines = 2
        self.view.addSubview(label)
    }
    
    @IBAction func checkTruncate(_ sender: Any) {
        let alertController = UIAlertController(title: "是否被截断",
                                                message: "\(label.isTruncated)",
                                                preferredStyle: .alert)
        let cancelAction = UIAlertAction(title: "确定", style: .cancel, handler: nil)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)
    }
}
评论0