简体   繁体   English

iphone UITextView设置行间距

[英]iphone UITextView set line spacing

如何在UITextView中增加行空间,使其在iPhone中看起来像“Notes”应用程序?

Well now on iOS6, there is a possibility, using NSParagraphStyle , but it is very poorly documented and seems to work seldomly. 那么现在在iOS6上,有一种可能性,使用NSParagraphStyle ,但它的文档很少,似乎很少工作。

I'm currently working about it like this: 我目前正在研究这样的事情:

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];

Problem is that when you set the Font, the line height stops working. 问题是,当您设置字体时,行高停止工作。 Very odd. 很奇怪。 I haven't found a fix for it yet. 我还没有找到解决方法。

Also you can create a custom Attributed CoreText view... but it's a bit more technical, you can find a demo of how it is done here 你也可以创建一个自定义的Attributed CoreText视图......但它更具技术性,你可以在这里找到它是如何完成的演示

Well I hope something helps. 好吧,我希望有所帮助。

With Swift 4 and iOS 11, according to your needs, you can choose one of the 3 following implementations in order to solve your problem. 使用Swift 4和iOS 11,根据您的需要,您可以选择以下3个实现中的一个来解决您的问题。


#1. #1。 Using String and UIFontDescriptorSymbolicTraits traitLooseLeading property 使用StringUIFontDescriptorSymbolicTraits traitLooseLeading属性

traitLooseLeading has the following declaration: traitLooseLeading具有以下声明:

The font uses looser leading values. 该字体使用更宽松的前导值。

static var traitLooseLeading: UIFontDescriptorSymbolicTraits { get }

The following code shows how to implement traitLooseLeading in order to have a looser font leading for your UItextView . 下面的代码演示如何实现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. #2。 Using NSAttributedString and NSMutableParagraphStyle lineSpacing property 使用NSAttributedStringNSMutableParagraphStyle lineSpacing属性

lineSpacing has the following declaration: lineSpacing具有以下声明:

The distance in points between the bottom of one line fragment and the top of the next. 一行片段底部与下一行片段顶部之间的距离。

var lineSpacing: CGFloat { get set }

The following code shows how to implement lineSpacing in order to have a specific line spacing for some attributed text in your UItextView . 下面的代码演示如何实现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. #3。 Using String and NSLayoutManagerDelegate protocol layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:) method 使用StringNSLayoutManagerDelegate协议layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:)方法

layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:) has the following declaration: layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:)具有以下声明:

Returns the spacing after the line ending with the given glyph index. 返回以给定的字形索引结束的行之后的间距。 [...] This message is sent while each line is laid out to enable the layout manager delegate to customize the shape of line. [...]在布置每一行时发送此消息,以使布局管理器委托能够自定义行的形状。

optional func layoutManager(_ layoutManager: NSLayoutManager, lineSpacingAfterGlyphAt glyphIndex: Int, withProposedLineFragmentRect rect: CGRect) -> CGFloat

The following code shows how to implement layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:) in order to have a specific line spacing for your UItextView . 下面的代码演示了如何实现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
    }

}

As an alternative to the previous code, the following code shows how to implement layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:) in a UITextView subclass. 作为前面代码的替代,以下代码显示了如何在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
    }

}

To change line spacing: 要更改行间距:

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;

A look at the documentation for UITextView is sufficient to determine that changing the line spacing is not supported by that control. 查看UITextView的文档就足以确定该控件不支持更改行间距。

For iOS 6 and above: 适用于iOS 6及更高版本:

There is a possibility, using NSParagraphStyle, 有可能,使用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];

For Swift 2.2 对于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)

If the end result is to increase line spacing, you can do it directly in interface builder. 如果最终结果是增加行间距,则可以直接在界面构建器中执行此操作。 Set the Text property to "Attributed" and then click the ... on the right. 将Text属性设置为“Attributed”,然后单击右侧的.... Setting the Spacing property there should update your line spacing correctly. 设置间距属性应该正确更新行间距。

In several answers above attribute lineHeightMultiple is misused: 在以上几个答案中,属性lineHeightMultiple被滥用:

paragraphStyle.lineHeightMultiple = 50.0f;

Following to the official documentation lineHeightMultiple is an multiplier and not an absolute height of a string: 在官方文档之后, lineHeightMultiple是一个乘数,而不是字符串的绝对高度:

The natural line height of the receiver is multiplied by this factor (if positive) before being constrained by minimum and maximum line height. 在受到最小和最大线高度约束之前,接收器的自然线高度乘以该因子(如果为正)。 The default value of this property is 0.0. 此属性的默认值为0.0。 https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index.html#//apple_ref/occ/instp/NSParagraphStyle/maximumLineHeight https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index.html#//apple_ref/occ/instp/NSParagraphStyle/maximumLineHeight

Thereby, the code below: 从而,代码如下:

paragraphStyle.lineHeightMultiple = 50.0f;
paragraphStyle.maximumLineHeight = 50.0f;
paragraphStyle.minimumLineHeight = 50.0f;

is equivalent to 相当于

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];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM