для iPhone UITextView установить межстрочный интервал
Как увеличить пространство строк в UITextView, чтобы оно выглядело как приложение "Заметки" в iPhone?
8 ответов
Ну теперь на iOS6 есть возможность, используя NSParagraphStyle, но он очень плохо документирован и, кажется, работает seldomly.
im в настоящее время работает об этом так:
UITextView *lab = [LocalTexts objectAtIndex:j];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineHeightMultiple = 50.0f;
paragraphStyle.maximumLineHeight = 50.0f;
paragraphStyle.minimumLineHeight = 50.0f;
NSString *string = lab.text;
NSDictionary *ats = @{
NSFontAttributeName : [UIFont fontWithName:@"DIN Medium" size:16.0f],
NSParagraphStyleAttributeName : paragraphStyle,
};
lab.attributedText = [[NSAttributedString alloc] initWithString:string attributes:ats];
проблема заключается в том, что при установке шрифта, высота строки перестает работать.. очень странно, я еще не нашел решение.
также можно создать пользовательское представление CoreText с атрибутом... но его немного более технический, вы можете найти демонстрацию того, как это делается здесь
надеюсь, что-то поможет.
чтобы изменить интервал между строками:
NSString *textViewText =self.myTextView.text;
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:textViewText];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 30;
NSDictionary *dict = @{NSParagraphStyleAttributeName : paragraphStyle };
[attributedString addAttributes:dict range:NSMakeRange(0, [textViewText length])];
self.myTextView.attributedText = attributedString;
достаточно взглянуть на документацию для UITextView, чтобы определить, что изменение межстрочного интервала не поддерживается этим элементом управления.
для iOS 6 и выше:
есть возможность, используя NSParagraphStyle,
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineHeightMultiple = 50.0f;
paragraphStyle.maximumLineHeight = 50.0f;
paragraphStyle.minimumLineHeight = 50.0f;
NSString *string = @"your paragraph here";
NSDictionary *attribute = @{
NSParagraphStyleAttributeName : paragraphStyle,
};
[textview setFont:[uifont fontwithname:@"Arial" size:20.0f]];
textview.attributedText = [[NSAttributedString alloc] initWithString:string attributes:attribute];
С Swift 4 и iOS 11, в соответствии с вашими потребностями, вы можете выбрать один из 3 следующие реализации для того, чтобы решить вашу проблему.
#1. Используя String
и UIFontDescriptorSymbolicTraits
traitLooseLeading
свойства
traitLooseLeading
есть следующее объявление:
шрифт использует более свободные ведущие значения.
static var traitLooseLeading: UIFontDescriptorSymbolicTraits { get }
следующий код показывает, как реализовать traitLooseLeading
для того, чтобы иметь более свободный шрифт, ведущий для вашего UItextView
.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let textView = UITextView()
view.addSubview(textView)
textView.text = """
Lorem ipsum
Dolor sit amet,
consectetur adipiscing elit
"""
if let fontDescriptor = UIFontDescriptor
.preferredFontDescriptor(withTextStyle: UIFontTextStyle.body)
.withSymbolicTraits(UIFontDescriptorSymbolicTraits.traitLooseLeading) {
let looseLeadingFont = UIFont(descriptor: fontDescriptor, size: 0)
textView.font = looseLeadingFont
}
// Layout textView
textView.translatesAutoresizingMaskIntoConstraints = false
textView.topAnchor.constraint(equalTo: view.readableContentGuide.topAnchor).isActive = true
textView.bottomAnchor.constraint(equalTo: view.readableContentGuide.bottomAnchor).isActive = true
textView.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor).isActive = true
textView.trailingAnchor.constraint(equalTo: view.readableContentGuide.trailingAnchor).isActive = true
}
}
#2. Используя NSAttributedString
и NSMutableParagraphStyle
lineSpacing
свойства
lineSpacing
есть следующее объявление:
расстояние в точках между нижней частью одного фрагмента строки и верхней частью следующего.
var lineSpacing: CGFloat { get set }
следующий код показывает, как реализовать lineSpacing
для того, чтобы иметь определенный интервал между строками для некоторого приписываемого текста в вашем UItextView
.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let string = """
Lorem ipsum
Dolor sit amet,
consectetur adipiscing elit
"""
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 15
let attributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.paragraphStyle: paragraphStyle]
let attributedString = NSAttributedString(string: string, attributes: attributes)
let textView = UITextView()
textView.attributedText = attributedString
view.addSubview(textView)
// Layout textView
textView.translatesAutoresizingMaskIntoConstraints = false
textView.topAnchor.constraint(equalTo: view.readableContentGuide.topAnchor).isActive = true
textView.bottomAnchor.constraint(equalTo: view.readableContentGuide.bottomAnchor).isActive = true
textView.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor).isActive = true
textView.trailingAnchor.constraint(equalTo: view.readableContentGuide.trailingAnchor).isActive = true
}
}
#3. Используя String
и NSLayoutManagerDelegate
протокол layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:)
метод
layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:)
есть следующее объявление:
возвращает интервал после строки, заканчивающейся заданным индексом глифа. [...] Это сообщение отправляется в то время как каждая строка выложена, чтобы позволить делегату диспетчера макетов настроить форму линии.
optional func layoutManager(_ layoutManager: NSLayoutManager, lineSpacingAfterGlyphAt glyphIndex: Int, withProposedLineFragmentRect rect: CGRect) -> CGFloat
следующий код показывает, как реализовать layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:)
чтобы иметь определенный интервал между строками для вашего UItextView
.
import UIKit
class ViewController: UIViewController, NSLayoutManagerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let textView = UITextView()
textView.layoutManager.delegate = self
view.addSubview(textView)
textView.text = """
Lorem ipsum
Dolor sit amet,
consectetur adipiscing elit
"""
// Layout textView
textView.translatesAutoresizingMaskIntoConstraints = false
textView.topAnchor.constraint(equalTo: view.readableContentGuide.topAnchor).isActive = true
textView.bottomAnchor.constraint(equalTo: view.readableContentGuide.bottomAnchor).isActive = true
textView.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor).isActive = true
textView.trailingAnchor.constraint(equalTo: view.readableContentGuide.trailingAnchor).isActive = true
}
// MARK: - NSLayoutManagerDelegate
func layoutManager(_ layoutManager: NSLayoutManager, lineSpacingAfterGlyphAt glyphIndex: Int, withProposedLineFragmentRect rect: CGRect) -> CGFloat {
return 15
}
}
в качестве альтернативы предыдущему коду следующий код показывает, как реализовать layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:)
в UITextView
подкласс.
import UIKit
class LineSpacingTextView: UITextView, NSLayoutManagerDelegate {
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
layoutManager.delegate = self
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - NSLayoutManagerDelegate
func layoutManager(_ layoutManager: NSLayoutManager, lineSpacingAfterGlyphAt glyphIndex: Int, withProposedLineFragmentRect rect: CGRect) -> CGFloat {
return 15
}
}
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let textView = LineSpacingTextView()
view.addSubview(textView)
textView.text = """
Lorem ipsum
Dolor sit amet,
consectetur adipiscing elit
"""
// Layout textView
textView.translatesAutoresizingMaskIntoConstraints = false
textView.topAnchor.constraint(equalTo: view.readableContentGuide.topAnchor).isActive = true
textView.bottomAnchor.constraint(equalTo: view.readableContentGuide.bottomAnchor).isActive = true
textView.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor).isActive = true
textView.trailingAnchor.constraint(equalTo: view.readableContentGuide.trailingAnchor).isActive = true
}
}
на Swift 2.2
let paragraphStyle: NSMutableParagraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineHeightMultiple = 20.0
paragraphStyle.maximumLineHeight = 20.0
paragraphStyle.minimumLineHeight = 20.0
let ats = [NSFontAttributeName: UIFont(name: "Helvetica Neue", size: 11.0)!, NSParagraphStyleAttributeName: paragraphStyle]
cell.textView.attributedText = NSAttributedString(string: "you string here", attributes: ats)
Если конечным результатом является увеличение межстрочного интервала, вы можете сделать это непосредственно в interface builder. Установите для свойства Text значение " Attributed "и нажмите кнопку... справа. Установка свойства Spacing должна корректно обновлять межстрочный интервал.
в нескольких ответах выше атрибута lineHeightMultiple
неправильно:
paragraphStyle.lineHeightMultiple = 50.0f;
следуя официальной документации lineHeightMultiple
является множителем, а не абсолютной высотой строки:
естественная высота линии приемника умножается на этот фактор (если положительный) до ограничения минимумом и максимальная высота линии. Значение этого свойства по умолчанию равно 0.0. https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index.html#//apple_ref/occ/instp/NSParagraphStyle/maximumLineHeight
таким образом, ниже код:
paragraphStyle.lineHeightMultiple = 50.0f;
paragraphStyle.maximumLineHeight = 50.0f;
paragraphStyle.minimumLineHeight = 50.0f;
эквивалентно
paragraphStyle.lineHeight = 50.0f
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineHeightMultiple = 50.0f;
paragraphStyle.maximumLineHeight = 50.0f;
paragraphStyle.minimumLineHeight = 50.0f;
NSString *string = @"if you want reduce or increase space between lines in uitextview ,you can do this with this,but donot set font on this paragraph , set this on uitextveiw.";
NSDictionary *ats = @{
NSParagraphStyleAttributeName : paragraphStyle,
};
[textview setFont:[uifont fontwithname:@"Arial" size:20.0f]];
textview.attributedText = [[NSAttributedString alloc] initWithString:string attributes:ats];