web-dev-qa-db-ja.com

Interface Builder内のUILabelの文字間隔を変更します

Interface Builderを使用してUILabelテキストの文字間隔(トラック)を変更する方法はありますか?そうでない場合は、属性付きテキストで既に作成された既存のUILabelでプログラムで行う方法はありますか?

45
codeman

これを今のところ使用して、既存の属性付きテキストを取得し、文字間隔を追加するように変更しました:

let attributedString = discoveryTitle.attributedText as NSMutableAttributedString
attributedString.addAttribute(NSKernAttributeName, value: 1.0, range: NSMakeRange(0, attributedString.length))
discoveryTitle.attributedText = attributedString

スウィフト3:

let attributedString = NSMutableAttributedString(string: discoveryTitle.text)
attributedString.addAttribute(NSKernAttributeName, value: CGFloat(1.0), range: NSRange(location: 0, length: attributedString.length))
discoveryTitle.attributedText = attributedString

NSMakeRangeの代わりにNSRangeを使用すると、Swift 3。

38
codeman

Interface Builderソリューションではないことは知っていますが、UILabel拡張を作成し、必要なUILabelにスペースを追加できます。

extension UILabel {
  func addCharacterSpacing(kernValue: Double = 1.15) {
    if let labelText = text, labelText.count > 0 {
      let attributedString = NSMutableAttributedString(string: labelText)
      attributedString.addAttribute(NSAttributedStringKey.kern, value: kernValue, range: NSRange(location: 0, length: attributedString.length - 1))
      attributedText = attributedString
    }
  }
}

デフォルトのkernValue1.15から設計に適したものに変更することを検討してください。


alwaysを実装する場合、テキスト値を設定した後に文字間隔を追加します。

myLabel.text = "We used to be so close"
myLabel.addCharacterSpacing()

アプリ内の異なる場所で異なる間隔を使用する場合、デフォルトのカーニング値をオーバーライドできます。

myLabelWithSpecialNeeds.addCharacterSpacing(kernValue: 1.3)
83
budidino

完全に静的なテキストの場合、ビューのヘッダー、または特にlaunchScreen0 opacityを使用して、わずかな幅(たとえば、 'l'文字)を占める文字を挿入できます。または、その色を背景と同じ色に設定します。

私はそれが最もきれいな解決策ではないという事実を知っていますが、それはコードを書かずに機能して仕事をする唯一の解決策です-あなたがXcodeで属性を指定することによってそれをすることができるまで。

The resultHow to

編集/追加のアイデア:間隔をさらに可変にするために、間にある充填文字のフォントサイズを変更できます。 @ mohamede1945 そのアイデアに感謝)

26
luk2302

Swift 3.2およびインターフェイスビルダー

extension UILabel {

    @IBInspectable
    var letterSpace: CGFloat {
        set {
            let attributedString: NSMutableAttributedString!
            if let currentAttrString = attributedText {
                attributedString = NSMutableAttributedString(attributedString: currentAttrString)
            }
            else {
                attributedString = NSMutableAttributedString(string: text ?? "")
                text = nil
            }

            attributedString.addAttribute(NSKernAttributeName,
                                           value: newValue,
                                           range: NSRange(location: 0, length: attributedString.length))

            attributedText = attributedString
        }

        get {
            if let currentLetterSpace = attributedText?.attribute(NSKernAttributeName, at: 0, effectiveRange: .none) as? CGFloat {
                return currentLetterSpace
            }
            else {
                return 0
            }
        }
    }
}

enter image description here

15
Mike Glukhov

これを試して!!

customLabelクラスを作成します

@interface CustomLabel : UILabel
@property (assign, nonatomic) CGFloat myLineSpacing;
@end


@implementation CustomLabel

- (void)setMyLineSpacing:(CGFloat)myLineSpacing {
    _myLineSpacing = myLineSpacing;
    self.text = self.text;
}

- (void)setText:(NSString *)text {
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineSpacing = _myLineSpacing;
    paragraphStyle.alignment = self.textAlignment;
    NSDictionary *attributes = @{NSParagraphStyleAttributeName: paragraphStyle};
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text
                                                                         attributes:attributes];
    self.attributedText = attributedText;
}

ランタイム属性の設定

enter image description here

これは実際には行間隔(別名leading.. (デジタル)行間に鉛(金属)を入れて行間のギャップを増やします文字間の間隔の場合、これはkerningと呼ばれます。ここにカーニングの方法があります https://stackoverflow.com/a/21141156/294884

9
Beslan Tularov

すべての人がNSMUTABLEAttributedStringを定義している理由。範囲を明示的に設定する必要はありません。絵文字が時々奇妙に見えるようにします。これは私のソリューションで、Swift 4でテストされています。 ????

extension UILabel {
    func addCharactersSpacing(_ value: CGFloat = 1.15) {
        if let textString = text {
            let attrs: [NSAttributedStringKey : Any] = [.kern: value]
            attributedText = NSAttributedString(string: textString, attributes: attrs)
        }
    }
}
7
Adam Smaka

Budidinhoの答えに触発されて、これは異なる行間隔のラベルの間隔を変更したい場合により柔軟なソリューションです。関数内に移動して値を変更する代わりに、単にパラメーターとして渡すことができます。

extension UILabel {
  func setTextSpacingBy(value: Double) {
    if let textString = self.text {
      let attributedString = NSMutableAttributedString(string: textString)
      attributedString.addAttribute(NSKernAttributeName, value: value, range: NSRange(location: 0, length: attributedString.length - 1))
      attributedText = attributedString
    }
  }
}
5
FredFlinstone

Swift 4 UILabel拡張:

import UIKit

extension UILabel {

    @IBInspectable
    var letterSpace: CGFloat {
        set {
            let attributedString: NSMutableAttributedString!
            if let currentAttrString = attributedText {
                attributedString = NSMutableAttributedString(attributedString: currentAttrString)
            } else {
                attributedString = NSMutableAttributedString(string: text ?? "")
                text = nil
            } 
            attributedString.addAttribute(NSAttributedString.Key.kern,
                                          value: newValue,
                                          range: NSRange(location: 0, length: attributedString.length))
            attributedText = attributedString
        }

        get {
            if let currentLetterSpace = attributedText?.attribute(NSAttributedString.Key.kern, at: 0, effectiveRange: .none) as? CGFloat {
                return currentLetterSpace
            } else {
                return 0
            }
        }
    }
}
4

Swift 4のソリューションは、既存のテキスト属性を上書きしません:

extension UILabel {

    /**
     Add kerning to a UILabel's existing `attributedText`
     - note: If `UILabel.attributedText` has not been set, the `UILabel.text`
     value will be returned from `attributedText` by default
     - note: This method must be called each time `UILabel.text` or
     `UILabel.attributedText` has been set
     - parameter kernValue: The value of the kerning to add
     */
    func addKern(_ kernValue: CGFloat) {
        guard let attributedText = attributedText,
            attributedText.string.count > 0,
            let fullRange = attributedText.string.range(of: attributedText.string) else {
                return
        }
        let updatedText = NSMutableAttributedString(attributedString: attributedText)
        updatedText.addAttributes([
            .kern: kernValue
            ], range: NSRange(fullRange, in: attributedText.string))
        self.attributedText = updatedText
    }
}
3
Max Paulson

これを試して。単純なテキストまたは属性付きテキストを設定して、割り当てる文字間隔を追加します。

open class UHBCustomLabel : UILabel {
    @IBInspectable open var characterSpacing: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))
        super.attributedText = attributedString
    }
}
2
Umair

プログラミングアプローチ(これを試してください、あなたのために働くはずです)
注:Swift 4でテストしました

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
1
Krunal

次のSwift 4 UILabel拡張を使用できます。これは、既存の設定を上書きしないように、既存の属性付きテキストとプレーンテキストの両方を考慮します。

import UIKit

extension UILabel {
    func addCharacterSpacing(_ kernValue: Double = 1.30) {
        guard let attributedString: NSMutableAttributedString = {
            if let text = self.text, !text.isEmpty {
                return NSMutableAttributedString(string: text)
            } else if let attributedText = self.attributedText {
                return NSMutableAttributedString(attributedString: attributedText)
            }
            return nil
            }() else { return}

        attributedString.addAttribute(
            NSAttributedString.Key.kern,
            value: kernValue,
            range: NSRange(location: 0, length: attributedString.length)
        )
        self.attributedText = attributedString
    }
}
1