如何控制UILabel中的行间距

当在UILabel中放入多行时,是否有可能减少文本之间的间隙?我们可以设置框架,字体大小和行数。我想减少标签中两行之间的差距。

269250 次浏览

我想在这个答案中加入一些新的东西,这样我就不会感觉那么糟糕了……下面是斯威夫特的答案:

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行间距


这是一个非常老的答案,其他人已经添加了新的更好的方法来处理这个问题。 . . .

这里有一个子类UILabel具有行高属性:https://github.com/LemonCake/MSLabel

在ios6中有另一个答案,那就是在标签上设置attributedText,使用NSAttributedString和适当的段落样式。关于NSAttributedString的行高,请参阅堆栈溢出答案:

核心文本- NSAttributedString行高度做对了吗?< / >

从ios6开始,你可以为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;

这里提到的解决方案对我不起作用。我发现了一个稍微不同的方式来做它与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];

在Xcode 6中,你可以在storyboard中这样做:

enter image description here

这段代码为我工作(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;

在Swift中,作为一个函数,灵感来自DarkDust

// 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
}

根据@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;
}

我做了这个简单的扩展,非常适合我:

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)

在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

斯威夫特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
}
}
}

在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
}

另一个答案……如果你通过编程的方式传递字符串,你需要传递一个带属性的字符串,而不是一个普通的字符串,并改变它的风格。

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;

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
}
}

从接口生成器(Storyboard/XIB):

enter image description here

编程:

斯威夫特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

我找到了一种方法,你可以设置实际线高(不是一个因素),它甚至呈现live in Interface Builder。按照下面的说明做就可以了。代码在斯威夫特4中编写。


创建一个名为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
}
}
}

第二步:UILabel放入Storyboard/XIB中,并将其类设置为DesignableLabel。等待项目构建完成(构建必须成功!)。

指定类到您的UILabel


现在你应该在属性窗格中看到一个名为“Line Height”的新属性。只要设置你喜欢的值,你应该立即看到结果!

Set Line Height in properties

这应该会有帮助。然后你可以将你的标签分配给故事板中的这个自定义类,并直接在属性中使用它的参数:

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
}
}
}

下面是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()
}
}

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
}
}

这是我在swift中的解决方案。子类应该同时适用于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
}
}