Help us understand the problem. What is going on with this article?

UILabelが省略されているか判定する

意外と見つからなくて困ったので、自分なりの実装方法を共有します。

コード

extension UILabel {

    var isOverflowing:Bool {
        return (realLineCount() > self.numberOfLines)
    }

    private func realLineCount()-> Int {
        guard let font = self.font else { return 0 }
        guard let text = self.text, text != "" else { return 0 }
        let sizeForWidthCheck = CGSize(width: Int.max, height: Int(ceil(font.pointSize)))

        let oneLineWidth = text.boundingRect(with: sizeForWidthCheck,
                                             options: .usesLineFragmentOrigin,
                                             attributes: [NSAttributedString.Key.font: font],
                                             context: nil).width
        let boundingWidth = text.boundingRect(with: self.bounds.size,
                                              options: .usesLineFragmentOrigin,
                                              attributes: [NSAttributedString.Key.font: font],
                                              context: nil).width
        return Int(ceil(oneLineWidth / boundingWidth))
    }

}

解説

UILabel.textは省略されている場合でも全文を返してくれるので、それを使用します。
realLineCountメソッドで、省略せずに全文を描画したときの行数を計算します。

let oneLineWidth = text.boundingRect(with: sizeForWidthCheck,
                                             options: .usesLineFragmentOrigin,
                                             attributes: [NSAttributedString.Key.font: font],
                                             context: nil).width

boundingRectメソッドはStringを描画した場合のRectを返してくれます。
これを使って、1行で全部描画したときの横幅を計算します。1

return Int(ceil(oneLineWidth / boundingWidth))

それをboundingWidth(Labelに描画したときの横幅)で割って、行数を計算します。2
小数点以下はいらないので、繰り上げます。

var isOverflowing:Bool {
    return (realLineCount() > self.numberOfLines)
}

計算した行数を自身の行数(ここは実際に表示される行数)と比較し、
大きければ省略されているのでtrueを返します。

純正で用意して欲しいな……

ありがとうございました。


  1. widthがInt.maxになっておりますが、
    こんなに使うことないと思うので適宜小さめの値に変えたほうが良いかもしれません。 

  2. 行数が増えると若干の誤差が出ると思います。(多分) 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした