简体   繁体   中英

How to detect UILabel (without set width just AutoLayout) is truncate like (Hello I am Test…) or not?

I want to detect UILabel is truncate or not.
And I try a UILabel extension function in stackoverflow and it return true to me.
But the UILabel line just one and no truncated, why return true to me.
Have another function to detect this situation like this.
Have any idea to me to fix this question? Thanks.


图片1

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)
        }

    }

}

Hope this help you :

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
}

Example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM