如何检测 UILabel(没有设置宽度只是 AutoLayout)是不是像(你好我是测试......)一样被截断?

Posted

技术标签:

【中文标题】如何检测 UILabel(没有设置宽度只是 AutoLayout)是不是像(你好我是测试......)一样被截断?【英文标题】:How to detect UILabel (without set width just AutoLayout) is truncate like (Hello I am Test....) or not?如何检测 UILabel(没有设置宽度只是 AutoLayout)是否像(你好我是测试......)一样被截断? 【发布时间】:2019-08-15 10:10:09 【问题描述】:

我想检测 UILabel 是否被截断。 我在 *** 中尝试了一个 UILabel 扩展函数,它对我返回 true。 但是 UILabel 行只有一个并且没有被截断,为什么要对我返回 true。 有另一个功能来检测这种情况。 有什么想法让我解决这个问题吗? 谢谢。

ViewController.swift

import UIKit
import SnapKit

class ViewController: UIViewController 

    let tableView = UITableView()

    var isExpand: Bool = false

    let titleArray: [String] = ["NAME", "AGE", "EMAIL", "TEL", "LOCATION"]
    let detailArray: [String] = ["abcdefghijklmnopqrstuvwxyz", "26", "XXXXXX@gmail.com", "XXXXXXXXXXX", "JP"]
    let hiddenArray: [Bool] = [false, true, true, false, false]

    override func viewDidLoad() 
        super.viewDidLoad()

        loadUI()
        loadLayout()
    

    fileprivate func tableviewSetting() 

        self.tableView.delegate = self
        self.tableView.dataSource = self
        self.tableView.estimatedRowHeight = 70
        self.tableView.rowHeight = UITableView.automaticDimension
        self.tableView.separatorStyle = .none
        self.tableView.backgroundColor = .clear
        self.tableView.register(TestTableViewCell.self, forCellReuseIdentifier: "TestTableViewCell")
    

    fileprivate func loadUI() 

        self.tableviewSetting()

        self.view.addSubview(tableView)
    

    fileprivate func loadLayout() 
        tableView.snp.makeConstraints  (make) in
            make.top.left.right.bottom.equalToSuperview()
        
    

    @objc func expandBtnPressed(sender: UIButton) 

        guard sender.tag == 0 else  return 

        let indexPath = IndexPath(row: sender.tag, section: 0)

        UIView.performWithoutAnimation 
            tableView.beginUpdates()
            self.isExpand = !isExpand
            tableView.reloadRows(at: [indexPath], with: .none)
            tableView.endUpdates()
        
    



extension ViewController: UITableViewDelegate, UITableViewDataSource 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

        return self.titleArray.count
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

        if indexPath.row == 0 

            let cell1 = tableView.dequeueReusableCell(withIdentifier: "TestTableViewCell", for: indexPath) as! TestTableViewCell
            cell1.titleLabel.text    = self.titleArray[indexPath.row]
            cell1.subtitleLabel.text = self.detailArray[indexPath.row]

            let bool = cell1.subtitleLabel.isTruncated()

            print("bool : \(bool)") // why this return true.

            return cell1
        

    



extension UILabel 

    func countLabelLines() -> Int 
        self.layoutIfNeeded()
        let myText = self.text! as NSString
        let attributes = [NSAttributedString.Key.font : self.font!]

        let labelSize = myText.boundingRect(with: CGSize(width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: attributes, context: nil)
        return Int(ceil(CGFloat(labelSize.height) / self.font.lineHeight))
    

    func isTruncated() -> Bool 

        if (self.countLabelLines() > self.numberOfLines) 
            print("lines         : \(self.countLabelLines())") // print : 2
            print("numberOfLines : \(self.numberOfLines)") // print : 1
            return true
        
        return false
    



TestTableViewCell.swift

import UIKit

class TestTableViewCell: UITableViewCell 

    let titleLabel: UILabel =  () -> UILabel in
        let ui = UILabel()
        ui.font = UIFont.systemFont(ofSize: 16)
        ui.sizeToFit()
        ui.translatesAutoresizingMaskIntoConstraints = false
        return ui
    ()

    let subtitleLabel: UILabel =  () -> UILabel in
        let ui = UILabel()
        ui.font = UIFont.systemFont(ofSize: 16)
        ui.numberOfLines = 1
        ui.adjustsFontSizeToFitWidth = false
        ui.lineBreakMode = .byTruncatingTail
        ui.translatesAutoresizingMaskIntoConstraints = false
        return ui
    ()

    override func awakeFromNib() 
        super.awakeFromNib()
    

    override func setSelected(_ selected: Bool, animated: Bool) 
        super.setSelected(selected, animated: animated)
    

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) 
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        self.selectionStyle = .none

        loadUI()
        loadLayout()
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    func loadUI() 

        addSubview(titleLabel)
        addSubview(subtitleLabel)
    

    func loadLayout() 

        titleLabel.snp.makeConstraints  (make) in
            make.top.equalTo(defaultfifteenPt)
            make.left.equalTo(defaultfifteenPt)
            make.width.equalTo(defaultNinetyTwoPt)
        

        subtitleLabel.snp.makeConstraints  (make) in
            make.top.equalTo(titleLabel.snp.top)
            make.left.equalTo(titleLabel.snp.right)
            make.bottom.equalTo(-defaultfifteenPt)
            make.right.equalTo(-defaultfifteenPt)
        

    


【问题讨论】:

【参考方案1】:

希望对您有所帮助:

func isTruncated(label: UILabel, containerFrame: CGSize) -> Bool 
    let text = label.text ?? ""
    let estimatedSize = NSString(string: text).boundingRect(with: .init(width: 100000, height: containerFrame.height), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font : label.font!], context: nil)
    return estimatedSize.width > containerFrame.width

例子:

let sampleLabel1 = UILabel()
sampleLabel1.text = "short text"
isTruncated(label: sampleLabel1, containerFrame: .init(width: 300, height: 15)) // return false

let sampleLabel2 = UILabel()
sampleLabel2.text = "short text fasjfojfosadjaof jasodfi jasodaj 
foiasdjfo isadjfoi jasdofj asdojf osiadjfo s"
isTruncated(label: sampleLabel2, containerFrame: .init(width: 300, height: 15)) // return true

【讨论】:

如果我想使用自动布局没有设置宽度? 即使您使用自动布局,标签仍然有框架。可以通过viewDidLayoutSubview方法获取 为什么要在函数isTruncated中设置.init(width: 100000)

以上是关于如何检测 UILabel(没有设置宽度只是 AutoLayout)是不是像(你好我是测试......)一样被截断?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式在 UILabel 上设置 sizeToFit 宽度和高度?

如何使用自动布局将 UILabel 设置为 UICell 宽度的百分比

多行 UILabel 与固有内容大小的 UILabel 宽度相同

如何滚动 UIlabel 文本并在目标 c 中动态设置它的宽度和高度

如何使用自动布局在一个宽度相同的 uitableviewcell 中设置八个 uilabel

iOS UILabel讲解以及根据字符串长度自动适应宽度和高度