Как контролировать межстрочный интервал в UILabel
можно ли уменьшить разрыв между текстом при вводе нескольких строк в UILabel
? Мы можем установить рамку, размер шрифта и количество строк. Я хочу уменьшить разрыв между двумя строками в этой метке.
22 ответа:
Я думал о добавлении чего-то нового к этому ответу, поэтому я не чувствую себя так плохо... Вот это Свифт ответ:
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
это действительно старый ответ, а другие уже добавили новый и лучший способ справиться с этим.. Пожалуйста, смотрите обновленные ответы, представленные ниже.
начиная с 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;
решения, изложенные здесь, не работают для меня. Я нашел немного другой способ сделать это с 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];
Я сделал это простое расширение, которое работает очень хорошо для меня:
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)
теперь в iOS 6 есть альтернативный ответ, который заключается в том, чтобы установить attributedText на метке, используя NSAttributedString с соответствующими стилями абзацев. См. этот ответ переполнения стека для получения подробной информации о высоте строки с помощью NSAttributedString:
основной текст-высота строки NSAttributedString сделано правильно?
из Interface Builder (Storyboard / 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
Swift 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
вот класс, который подкласс UILabel имеет свойство line-height:https://github.com/LemonCake/MSLabel
в 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(NSParagraphStyleAttributeName, 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; }
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 } } }
В 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))
очевидно, я добавил кучу параметров, которые вам могут не понадобиться. Поиграйте - не стесняйтесь переписывать метод - я искал это на куче разных ответов, поэтому решил, что опубликую все расширение, если это поможет кому-то там... - РЭБ
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 }
другого ответа... Если вы передаете строку программно, вам нужно передать атрибутивную строку вместо обычной строки и изменить ее стиль.(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;
расширение 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 } }
Я нашел способ, где вы можете установить реальная высота строки (не фактор), и это даже делает жить в 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
. Ждать ваш проект для сборки (Сборка должна быть успешной!).
Шаг 3: теперь вы должны увидеть новое свойство в панели свойств с именем "высота линии". Просто установите значение, которое вам нравится, и вы должны сразу увидеть результат!
этот код работал для меня (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;
Это должно помочь с этим. Затем вы можете назначить свою метку этому пользовательскому классу в раскадровке и использовать его параметры непосредственно в свойствах:
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 } }
Как быстро-грязный-умный-простой обходной путь:
для UILabels, которые не имеют много строк, вы можете вместо этого использовать stackViews.
- для каждой строки напишите новую метку.
- встроить их в StackView.(выберите обе метки-- > редактор-- > вставить в -->StackView
- изменить
Spacing
из StackView в нужное вам количествообязательно стек их вертикально. Это решение также работает для пользовательский шрифт.