Interface Builderを使用してUILabelテキストの文字間隔(トラック)を変更する方法はありますか?そうでない場合は、属性付きテキストで既に作成された既存のUILabelでプログラムで行う方法はありますか?
これを今のところ使用して、既存の属性付きテキストを取得し、文字間隔を追加するように変更しました:
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。
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
}
}
}
デフォルトのkernValue
を1.15
から設計に適したものに変更することを検討してください。
alwaysを実装する場合、テキスト値を設定した後に文字間隔を追加します。
myLabel.text = "We used to be so close"
myLabel.addCharacterSpacing()
アプリ内の異なる場所で異なる間隔を使用する場合、デフォルトのカーニング値をオーバーライドできます。
myLabelWithSpecialNeeds.addCharacterSpacing(kernValue: 1.3)
完全に静的なテキストの場合、ビューのヘッダー、または特にlaunchScreen、0 opacity
を使用して、わずかな幅(たとえば、 'l'文字)を占める文字を挿入できます。または、その色を背景と同じ色に設定します。
私はそれが最もきれいな解決策ではないという事実を知っていますが、それはコードを書かずに機能して仕事をする唯一の解決策です-あなたがXcodeで属性を指定することによってそれをすることができるまで。
編集/追加のアイデア:間隔をさらに可変にするために、間にある充填文字のフォントサイズを変更できます。 ( @ mohamede1945 そのアイデアに感謝)
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
}
}
}
}
これを試して!!
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;
}
ランタイム属性の設定
注これは実際には行間隔(別名leading.. (デジタル)行間に鉛(金属)を入れて行間のギャップを増やします文字間の間隔の場合、これはkerningと呼ばれます。ここにカーニングの方法があります https://stackoverflow.com/a/21141156/294884
すべての人が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)
}
}
}
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
}
}
}
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
}
}
}
}
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
}
}
これを試して。単純なテキストまたは属性付きテキストを設定して、割り当てる文字間隔を追加します。
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
}
}
プログラミングアプローチ(これを試してください、あなたのために働くはずです)
注: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
次の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
}
}