文字列表示で行間をいじる時、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行のみの表示の時、下に本来は入るはずのない行間のスペースが入ってしまいます。
(原因はわかりませんでした。。)
複数行やアルファベットの時は想定通りになります。
対策
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
}
}
これで日本語1行の時でも変なスペースが開かなくなりました。
TextKitとか使ってもうちょっと厳密にやってもいい気はしますが、今回は問題なかったので一旦放置。
##その他
もっといい実装ありましたらコメントいただければと思います!
それとNSAttributedStringを扱う時はこれ使うとめっちゃ楽!
https://github.com/delba/TextAttributes
この実装のサンプルは以下になります。
https://github.com/furuyan/LineSpacingSapmle