【问题标题】:iphone UITextView set line spacingiphone UITextView 设置行距
【发布时间】:2010-11-25 13:26:52
【问题描述】:

如何增加 UITextView 中的行距,使其看起来像 iPhone 中的“Notes”应用?

【问题讨论】:

  • 对于 Swift 4 和 iOS 11,请参阅 this answer,其中显示了多达 3 种不同的方法来解决您的问题。

标签: ios iphone uitextview


【解决方案1】:

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

}

【讨论】:

  • 谢谢!最后的实现是最好的。
【解决方案2】:

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

问题是当您设置字体时,行高停止工作。很奇怪。我还没有找到解决办法。

你也可以创建一个自定义的 Attributed CoreText 视图...但它的技术性更强,你可以找到一个演示它是如何完成的 here

我希望能有所帮助。

【讨论】:

  • 特别是如果文档记录不佳,您可能希望链接到您拥有找到的任何好的文档
【解决方案3】:

改变行距:

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;

【讨论】:

  • 确认工作。需要注意的是,如果看起来低至 1 并没有什么不同的话,你可能需要负数才能得到你想要的东西。
【解决方案4】:

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

【讨论】:

  • 那么 Notes 应用程序如何允许行间距?
  • 使用CoreText实现
  • 很高兴听到这个消息。有没有使用核心文本的教程或示例?
  • 它只适用于 MacOs X...你应该为 iphone 做很多改变
【解决方案5】:

对于 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)

【讨论】:

  • 让paragraphStyle = NSMutableParagraphStyle();段落样式.lineSpacing = 6
【解决方案6】:

如果最终结果是增加行距,您可以直接在界面生成器中进行。将 Text 属性设置为“Attributed”,然后单击右侧的 ...。在那里设置 Spacing 属性应该会正确更新行距。

【讨论】:

    【解决方案7】:

    在上面的几个答案中,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
    

    【讨论】:

      【解决方案8】:
       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];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-18
        • 2011-05-19
        • 2011-03-31
        • 1970-01-01
        • 2011-03-14
        • 2014-10-10
        • 2011-04-20
        • 1970-01-01
        相关资源
        最近更新 更多