9
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

日本語で行間をいじった時のバグ

Last updated at Posted at 2017-01-06

文字列表示で行間をいじる時、NSAttributedString,NSParagraphStyleを使うと思います。

let style = NSMutableParagraphStyle()
style.lineSpacing = 10.0 // 行間設定
        
let attr = [NSParagraphStyleAttributeName: style, NSFontAttributeName: font]
let attrStr = NSMutableAttributedString(string: text, attributes: attr)
label.attributedText = attrStr

ただ日本語で1行のみの表示の時、下に本来は入るはずのない行間のスペースが入ってしまいます。
(原因はわかりませんでした。。)
複数行やアルファベットの時は想定通りになります。

スクリーンショット 2017-01-06 11.05.26.png

対策

1行の場合かつ高さがフォントの高さ+行間スペースの場合のみ高さをフォントの高さに合わせるサブクラスを実装しました。

class LineSpacingLabel: UILabel {
    var adjustedHeight = CGFloat(0.0)
    var adjustedForLineSpacingBug = false
    
    override func drawText(in rect: CGRect) {
        var baseRect = rect
        
        // 本来の描画されるスペースを小さくしているため、そのままにすると上下が切れてしまうのでここで調整する
        if adjustedForLineSpacingBug {
            baseRect.origin.y = adjustedHeight / 2.0
        }
        
        super.drawText(in: baseRect)
    }
    
    override var intrinsicContentSize: CGSize {
        let baseSize = super.intrinsicContentSize
        
        adjustedHeight = 0.0
        adjustedForLineSpacingBug = false
        
        // lineSpacingを設定しているかつlineSpacingが0以外の時のみ処理を行う
        if let paragraphStyle = attributedText?.attribute(NSParagraphStyleAttributeName, at: 0, effectiveRange: nil) as? NSParagraphStyle,
            paragraphStyle.lineSpacing != 0.0 {
         
            let fontHeight = ceil(self.font.lineHeight)
            let lineSpacing = paragraphStyle.lineSpacing
            
            // 固有サイズの高さがフォントの高さ+行間スペースの場合(1行だけど下に行間スペースが挿入されている場合)
            // 本来の高さに変更する
            if baseSize.height == fontHeight + lineSpacing {
                adjustedHeight = lineSpacing
                adjustedForLineSpacingBug = true
                return CGSize(width: baseSize.width, height: fontHeight)
            }
        }
        
        return baseSize
    }
}

スクリーンショット 2017-01-06 11.30.57.png

これで日本語1行の時でも変なスペースが開かなくなりました。
TextKitとか使ってもうちょっと厳密にやってもいい気はしますが、今回は問題なかったので一旦放置。

##その他
もっといい実装ありましたらコメントいただければと思います!

それとNSAttributedStringを扱う時はこれ使うとめっちゃ楽!
https://github.com/delba/TextAttributes

この実装のサンプルは以下になります。
https://github.com/furuyan/LineSpacingSapmle

9
12
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?