UILabelで行間隔を制御する方法


274

aに複数行を入れると、テキスト間のギャップを減らすことはできUILabelますか?フレーム、フォントサイズ、行数を設定できます。そのラベルの2つの行の間のギャップを減らしたいのですが。



2
iOS 6.0以降で正しい答えを1つ受け入れることをお勧めしますか?現在受け入れられている回答は古くなっています。
Mark Amery 2013年

行ごとに新しいを使用し、UILabelすべてのラベルをに埋め込みますStackView。最後に調整するspacingのをStackView。それらを垂直に積み重ねることを忘れないでください。
ハニー

スウィフト2で解決策については、以下のリンクを参照してくださいstackoverflow.com/a/39158698/6602495
スネハ

ストーリーボードの調整やその他の詳細については、stackoverflow.com / a / 44325650/342794を参照してください。
lal 2018年

回答:


262

この回答に新しいものを追加することを考えたので、それほど気分が悪くなりません...これがSwiftの回答です。

import Cocoa

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 40

let attrString = NSMutableAttributedString(string: "Swift Answer")
attrString.addAttribute(.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))

var tableViewCell = NSTableCellView()
tableViewCell.textField.attributedStringValue = attrString

「簡単な回答:できません。テキストの行間の間隔を変更するには、UILabelをサブクラス化して独自のdrawTextInRectをロールするか、複数のラベルを作成する必要があります。」

参照項目:UILabel行間隔の設定


これは本当に古い答えです、そして他の人はこれを処理するための新しいより良い方法をすでに追加しています。以下に提供される最新の答えを見てください。


23
iOS 6.0以降では、それを制御NSAttributedStringできます(XcodeのインターフェイスビルダーのUILableのプロパティでも使用可能)。
ıɾuǝʞ

13
興味深いことに、私が知る限りでは、行間に余分なスペースを追加できますが、NSParagraphStyleを使用する場合はを介してそれを減らすことはできませんNSAttributedString。(他の変更可能なプロパティのテストをさらに行う必要があるかもしれませんが、lineSpacingプロパティではそれを増やすことしかできません。)
livingtech

参照私の答えを NSAttributedStringを使用する方法を参照してください
d.ennis

2
@livingtechそれは腹立たしいです、そして私はあなたが正しいと信じています。回避策を見つけましたか?
Dom Vinyard 2014年

7
このスレッドで何かを明確にするために。行間隔を縮小する場合は、行の高さを1.0に設定してから、setLineHeightMultipleを1.0未満の低い値に設定します。たとえば、[paragraphStyle setLineHeightMultiple:0.8]または段落
スタイル.lineHeightMultiple

401

Xcode 6では、ストーリーボードでこれを行うことができます。

enter image description here


1
ストーリーボードをもっと活用しよう!
アレン

22
@PaperThickには6.1.1と同じ問題があります。数分間「ハーレムシェイク」。それを修正する方法がわかりません:) Xcode Shaking
Anton Gaenko

8
この方法でカスタムフォントを設定する方法はありますか?そのhelvetica neueを他のフォントに変更することはできません。
Marcos Curvello 2015

2
「属性」を有効にして、ファイルをソースコードとして開くと、「lineHeightMultiple」を手動で編集できるため、ハーレムシェイクのバグを回避できます
ED-209

2
@azdevまだこれを見ている人のために、私はXcode 7.3でシェイクを長くするつもりですが、これは問題がなかった最初のバージョンだと思います
LulzCow

103

iOS 6以降、属性付き文字列をUILabelに設定できます。以下を確認してください。

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:label.text];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = spacing;
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, label.text.length)];

label.attributedText = attributedString;

1
attributedStringでなければならないNSMutableAttributedString(NOT NSAttributedString)
マイク・S

14
最初の行のコードは次のNSMutableAttributedString *attributedString = [NSMutableAttributedString alloc]initWithString:@"sample text"];
アレン

lineSpacingプロパティがNSMutableParagraphStyle負になることはないため、この方法では行の高さを下げることはできません。質問に回答するには、別のプロパティを使用する必要があります。@ d.ennisの回答を参照してください。
Theo

81

ここで述べた解決策は私にはうまくいきませんでした。iOS 6 NSAttributeStringでそれを行うには少し異なる方法を見つけました:

myLabel.numberOfLines = 0; 
NSString* string = @"String with line one. \n Line two. \n Line three.";
NSMutableParagraphStyle *style  = [[NSMutableParagraphStyle alloc] init];
style.minimumLineHeight = 30.f;
style.maximumLineHeight = 30.f;
NSDictionary *attributtes = @{NSParagraphStyleAttributeName : style,};
myLabel.attributedText = [[NSAttributedString alloc] initWithString:string
                                                         attributes:attributtes];   
[myLabel sizeToFit];

1
行の高さはフォントサイズに依存します。行間隔は、行間隔です。最小/最大の行の高さを設定するだけで問題が解決する場合がありますが、これは、現在使用しているフォントサイズが行の高さの境界より大きくないためです。ドキュメントによると:「...この高さを超えるグリフとグラフィックスは隣接する行と重なります...この制限は行自体に適用されますが、行間隔は隣接する行の間に余分なスペースを追加します。」
Ari Braginsky 2013年

+1、行間の間隔を狭くしたい場合、これはあなたがしたいことです。実際の行間はデフォルトで0である可能性が最も高いため、これを増やすことしかできないと報告されています。間隔が大きすぎるという問題は、行の高さが大きすぎることに起因します。これが、99%の時間でジョブを完了させる理由です。
lawicko 2015年

1
これは私が(代わり比の)実際の行の高さの値を使用していますなどのPhotoshop、スケッチ、CSS、などの設計アプリケーションに共通する見つけることができる答えである
アルバートBori

35

私は私にとって非常にうまく機能するこの単純な拡張を作成しました:

extension UILabel {
    func setLineHeight(lineHeight: CGFloat) {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 1.0
        paragraphStyle.lineHeightMultiple = lineHeight
        paragraphStyle.alignment = self.textAlignment

        let attrString = NSMutableAttributedString()
        if (self.attributedText != nil) {
            attrString.append( self.attributedText!)
        } else {
            attrString.append( NSMutableAttributedString(string: self.text!))
            attrString.addAttribute(NSAttributedStringKey.font, value: self.font, range: NSMakeRange(0, attrString.length))
        }
        attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
        self.attributedText = attrString
    }
}

これをファイルにコピーすると、次のように使用できます

myLabel.setLineHeight(0.7)

このラベルにストーリーボードも使用しているときにこれを行う場合は、ラベルの行を0に設定してください
Honey

直接設定してlineSpacing、設定を忘れないのはなぜlineHeightMultipleですか?
ハニー

行の高さを減らすためのキーは「lineHeightMultiple」であるため、lineSpacingはありません
Agustin Meriles

なぜあなただけ書くことができない、あなたは行の高さが1.4になりたいと言う.lineSpacing = 1.4すべてについてと忘れて.lineHeightMultiple...
ハニー

はぁ!私は試しましたが、うまくいきませんでしたが、なぜあなたのメカニズムを使用していない他の答えがここに表示されないのでしょうか?彼らは直接lineSpacingを設定するだけです。受け入れられた回答を参照してください...
ハニー

33

Interface Builder(ストーリーボード/ XIB)から:

ここに画像の説明を入力してください

プログラム的に:

SWift 4

ラベル拡張の使用

extension UILabel {

    // Pass value for any one of both parameters and see result
    func setLineSpacing(lineSpacing: CGFloat = 0.0, lineHeightMultiple: CGFloat = 0.0) {

        guard let labelText = self.text else { return }

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = lineSpacing
        paragraphStyle.lineHeightMultiple = lineHeightMultiple

        let attributedString:NSMutableAttributedString
        if let labelattributedText = self.attributedText {
            attributedString = NSMutableAttributedString(attributedString: labelattributedText)
        } else {
            attributedString = NSMutableAttributedString(string: labelText)
        }

        // Line spacing attribute
        attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))

        self.attributedText = attributedString
    }
}

拡張機能を呼び出します

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"

// Pass value for any one argument - lineSpacing or lineHeightMultiple
label.setLineSpacing(lineSpacing: 2.0) .  // try values 1.0 to 5.0

// or try lineHeightMultiple
//label.setLineSpacing(lineHeightMultiple = 2.0) // try values 0.5 to 2.0

またはラベルインスタンスを使用する(結果を確認するには、このコードをコピーして実行するだけです)

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40

// Line spacing attribute
attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: style, range: NSRange(location: 0, length: stringValue.characters.count))

// Character spacing attribute
attrString.addAttribute(NSAttributedStringKey.kern, value: 2, range: NSMakeRange(0, attrString.length))

label.attributedText = attrString

スウィフト3

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
attrString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
label.attributedText = attrString

2
行「paragraphStyle.alignment = self.textAlignment」を追加して、元の配置を維持します。それ以外の場合、テキストは左揃えになります。
Nithin Michael

大きなテキストで省略記号を失った人は、次を使用します。paragraphStyle.lineBreakMode= .byTruncatingTail
christostsang



11

DarkDustに触発されたSwiftおよび関数として

// Usage: setTextWithLineSpacing(myEpicUILabel,text:"Hello",lineSpacing:20)
func setTextWithLineSpacing(label:UILabel,text:String,lineSpacing:CGFloat)
{
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = lineSpacing

    let attrString = NSMutableAttributedString(string: text)
    attrString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))

    label.attributedText = attrString
}

7

@Mikeの回答によれば、削減することlineHeightMultipleが重要なポイントです。以下の例、それは私にとってうまくいきます:

    NSString* text = label.text;
    CGFloat textWidth = [text sizeWithAttributes:@{NSFontAttributeName: label.font}].width;
    if (textWidth > label.frame.size.width) {
        NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
        paragraph.alignment = NSTextAlignmentCenter;
        paragraph.lineSpacing = 1.0f;
        paragraph.lineHeightMultiple = 0.75;     // Reduce this value !!!
        NSMutableAttributedString* attrText = [[NSMutableAttributedString alloc] initWithString:text];
        [attrText addAttribute:NSParagraphStyleAttributeName value:paragraph range:NSMakeRange(0, text.length)];
        label.attributedText = attrText;
    }

6

SWIFT 3は、行間のスペースをより簡単に設定するための便利な拡張機能です:)

extension UILabel
{
    func setLineHeight(lineHeight: CGFloat)
    {
        let text = self.text
        if let text = text 
        {

            let attributeString = NSMutableAttributedString(string: text)
            let style = NSMutableParagraphStyle()

           style.lineSpacing = lineHeight
           attributeString.addAttribute(NSParagraphStyleAttributeName,
                                        value: style,
                                        range: NSMakeRange(0, text.characters.count))

           self.attributedText = attributeString
        }
    }
}

5

実際の行の高さ(係数ではない)を設定して、Interface Builderでライブにレンダリングする方法を見つけました。以下の手順に従ってください。コードはSwift 4で書かれています。


ステップ#1:という名前のファイルを作成しDesignableLabel.swift、次のコードを挿入します。

import UIKit

@IBDesignable
class DesignableLabel: UILabel {
    @IBInspectable var lineHeight: CGFloat = 20 {
        didSet {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.minimumLineHeight = lineHeight
            paragraphStyle.maximumLineHeight = lineHeight
            paragraphStyle.alignment = self.textAlignment

            let attrString = NSMutableAttributedString(string: text!)
            attrString.addAttribute(NSAttributedStringKey.font, value: font, range: NSRange(location: 0, length: attrString.length))
            attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attrString.length))
            attributedText = attrString
        }
    }
}

ステップ#2:置きUILabelストーリーボード/ XIBにとにそのクラスを設定しますDesignableLabel。プロジェクトがビルドされるのを待ちます(ビルドは成功する必要があります!)。

UILabelにクラスを指定する


ステップ3:これで、「行の高さ」という名前のプロパティペインに新しいプロパティが表示されます。好きな値を設定するだけで、すぐに結果表示されます。

プロパティで行の高さを設定する


2

以下は、UILabelのサブクラスでlineHeightMultiple、固有の高さがテキストを切り取らないように十分な大きさに設定および確認します。

@IBDesignable
class Label: UILabel {
    override var intrinsicContentSize: CGSize {
        var size = super.intrinsicContentSize
        let padding = (1.0 - lineHeightMultiple) * font.pointSize
        size.height += padding
        return size
    }

    override var text: String? {
        didSet {
            updateAttributedText()
        }
    }

    @IBInspectable var lineHeightMultiple: CGFloat = 1.0 {
        didSet {
            updateAttributedText()
        }
    }

    private func updateAttributedText() {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineHeightMultiple = lineHeightMultiple
        attributedText = NSAttributedString(string: text ?? "", attributes: [
            .font: font,
            .paragraphStyle: paragraphStyle,
            .foregroundColor: textColor
        ])
        invalidateIntrinsicContentSize()
    }
}

追加のパディングは(lineHeightMultiple-1.0)* font.pointSizeである必要がありますよね?
Pavel Alexeev

上記のコードは私には問題なく動作するようです。しかし、多分あなたは正しいです。変更を試しましたか?@PavelAlexeev
ファットマン

いいえ、lineHeightMultipleではなくlineSpacingを使用します:)
Pavel Alexeev

1

Swift 2.0では...

拡張機能を追加します。

extension UIView {
    func attributesWithLineHeight(font: String, color: UIColor, fontSize: CGFloat, kern: Double, lineHeightMultiple: CGFloat) -> [String: NSObject] {
        let titleParagraphStyle = NSMutableParagraphStyle()
        titleParagraphStyle.lineHeightMultiple = lineHeightMultiple

        let attribute = [
            NSForegroundColorAttributeName: color,
            NSKernAttributeName: kern,
            NSFontAttributeName : UIFont(name: font, size: fontSize)!,
            NSParagraphStyleAttributeName: titleParagraphStyle
        ]
        return attribute
    }
}

次に、UILabelをattributedTextとして設定します。

self.label.attributedText = NSMutableAttributedString(string: "SwiftExample", attributes: attributesWithLineHeight("SourceSans-Regular", color: UIColor.whiteColor(), fontSize: 20, kern: 2.0, lineHeightMultiple: 0.5))    

明らかに、必要のないパラメータをたくさん追加しました。遊んでみてください-メソッドを自由に書き直してください-私はさまざまな答えでこれを探していたので、誰かが助けになる場合に備えて、拡張機能全体を投稿すると思いました... -rab


1

Swift3-UITextViewまたはUILabel拡張で、次の関数を追加します。

ビューで属性付き文字列を既に使用している場合(それらを上書きするのではなく)、現在の属性付きテキストを保持するコードを追加しました。

func setLineHeight(_ lineHeight: CGFloat) {
    guard let text = self.text, let font = self.font else { return }

    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = 1.0
    paragraphStyle.lineHeightMultiple = lineHeight
    paragraphStyle.alignment = self.textAlignment

    var attrString:NSMutableAttributedString
    if let attributed = self.attributedText {
        attrString = NSMutableAttributedString(attributedString: attributed)
    } else {
        attrString = NSMutableAttributedString(string: text)
        attrString.addAttribute(NSFontAttributeName, value: font, range: NSMakeRange(0, attrString.length))
    }
    attrString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
    self.attributedText = attrString
}

1

別の答え...プログラムで文字列を渡す場合は、通常の文字列ではなく属性付き文字列を渡し、スタイルを変更する必要があります。(iOS10)

NSMutableAttributedString * attrString = [[NSMutableAttributedString alloc] initWithString:@"Your \nregular \nstring"];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:4];
[attrString addAttribute:NSParagraphStyleAttributeName
                   value:style
                   range:NSMakeRange(0, attrString.length)];
_label.attributedText = attrString;

1

Swift 3拡張:

    import UIKit

extension UILabel {
    func setTextWithLineSpacing(text: String, lineHeightMultiply: CGFloat = 1.3) {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineHeightMultiple = lineHeightMultiply
        paragraphStyle.alignment = .center
        let attributedString = NSMutableAttributedString(string: text)
        attributedString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSRange(location: 0, length: attributedString.length))
        self.attributedText = attributedString
    }
}

1

これはそれを助けるはずです。次に、ストーリーボード内のこのカスタムクラスにラベルを割り当て、そのパラメーターをプロパティ内で直接使用できます。

open class SpacingLabel : UILabel {

    @IBInspectable open var lineHeight:CGFloat = 1 {
        didSet {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = 1.0
            paragraphStyle.lineHeightMultiple = self.lineHeight
            paragraphStyle.alignment = self.textAlignment

            let attrString = NSMutableAttributedString(string: self.text!)
            attrString.addAttribute(NSAttributedStringKey.font, value: self.font, range: NSMakeRange(0, attrString.length))
            attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
            self.attributedText = attrString
        }
    } 
}

これはそれを助けるはずです。次に、ストーリーボード内のこのカスタムクラスにラベルを割り当て、そのパラメーターをプロパティ内で直接使用できます。
ラッセルワーウィック

回答に関連するコンテンツをコメントに含めないでください。あなたの答えは、コメント
Neuron

1

Swift 4ラベル拡張。属性付きテキストに追加の属性が必要な場合に備えて、関数に渡す前にNSMutableAttributedStringを作成します。

extension UILabel {

    func setLineHeightMultiple(to height: CGFloat, withAttributedText attributedText: NSMutableAttributedString) {

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 1.0
        paragraphStyle.lineHeightMultiple = height
        paragraphStyle.alignment = textAlignment

        attributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedText.length - 1))

        self.attributedText = attributedText
    }
}

0

このコードは私のために働いた(確かにiOS 7とiOS 8)。

_label.numberOfLines=2;
_label.textColor=[UIColor whiteColor];

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineHeightMultiple=0.5;
paragraphStyle.alignment = NSTextAlignmentCenter;
paragraphStyle.lineSpacing = 1.0;

NSDictionary *nameAttributes=@{
                               NSParagraphStyleAttributeName : paragraphStyle,
                               NSBaselineOffsetAttributeName:@2.0
                               };


NSAttributedString *string=[[NSAttributedString alloc] initWithString:@"22m\nago" attributes:nameAttributes];
_label.attributedText=string;

0

これが迅速な私の解決策です。サブクラスは、attributedTextとtextプロパティの両方、およびcharacterSpacing + lineSpacingに対して機能する必要があります。新しい文字列またはattributedStringが設定されている場合、間隔は保持されます。

open class UHBCustomLabel : UILabel {
    @IBInspectable open var characterSpacing:CGFloat = 1 {
        didSet {
            updateWithSpacing()
        }

    }
    @IBInspectable open var lines_spacing:CGFloat = -1 {
        didSet {
            updateWithSpacing()
        }

    }
    open override var text: String? {
        set {
            super.text = newValue
            updateWithSpacing()
        }
        get {
            return super.text
        }
    }
    open override var attributedText: NSAttributedString? {
        set {
            super.attributedText = newValue
            updateWithSpacing() 
        }
        get {
            return super.attributedText
        }
    }
    func updateWithSpacing() {
        let attributedString = self.attributedText == nil ? NSMutableAttributedString(string: self.text ?? "") : NSMutableAttributedString(attributedString: attributedText!)
        attributedString.addAttribute(NSKernAttributeName, value: self.characterSpacing, range: NSRange(location: 0, length: attributedString.length))
        if lines_spacing >= 0 {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = lines_spacing
            paragraphStyle.alignment = textAlignment
            attributedString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
        }
        super.attributedText = attributedString
    }
}

-5

すばやくダーティ、スマート、シンプルな回避策として:

行数が少ないUILabelsの場合は、代わりにstackViewsを使用できます。

  1. 各行に新しいラベルを書きます。
  2. それらをStackViewに埋め込みます(両方のラベルを選択します-> Editor-> Embed In-> StackView
  3. SpacingStackViewを必要な量に調整します

必ず垂直に積み重ねてください。このソリューションは、カスタムフォントでも機能します。

ここに画像の説明を入力してください


FWIWこれはひどいが実行可能なソリューションです。したがって、私はそれを維持しています。
Honey

また、iOS開発者がグラフを作成するためにスタックビューを使用することも確認しました。Stackviewsは非常に強力です
Honey
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.