我如何增加UITextView的行间距,使其看起来像iPhone中的“Notes”应用程序?
我如何增加UITextView的行间距,使其看起来像iPhone中的“Notes”应用程序?
使用 Swift 4 和 iOS 11,根据您的需求,您可以选择以下3种实现方式之一来解决问题。
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
}
}
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
}
}
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
}
}
作为之前代码的替代方案,下面的代码展示了如何在一个UITextView
子类中实现layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:)
方法。
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
}
}
现在在iOS6上,可以使用NSParagraphStyle
,但是文档非常不完善,似乎很少起作用。
我目前正在尝试以下方式解决它:
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 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)
如果最终目的是增加行间距,你可以直接在界面构建器中进行。将Text属性设置为“Attributed”,然后单击右侧的“...”。在那里设置Spacing属性应该能正确更新您的行间距。
lineHeightMultiple
被错误使用了:paragraphStyle.lineHeightMultiple = 50.0f;
lineHeightMultiple
是一种乘数,而不是字符串的绝对高度: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];