在UITextView中设置行高

Max*_*ann 58 iphone cocoa-touch

我已经非常确定无法使用任何公共API,但我仍然想问:

有没有办法在UITextView中更改行高?

足以静态地完成它,不需要在运行时更改它.问题是默认的行高只是太小了.在尝试编写较长的文本时,文本看起来会非常压缩并且是一场噩梦.

谢谢,马克斯

编辑:我知道有它UIWebView,它很好,可以做样式等但它不可编辑.我需要一个可编辑的文本组件,其行高可以接受.来自Omni Frameworks的东西也无济于事,因为它太慢而感觉不对......

Gra*_*rks 106

在iOS 7之后,styleString方法不再有效.

有两种新的替代品.

首先,TextKit; 强大的新布局引擎.要更改行间距,请设置UITextView的布局管理器委托:

textView.layoutManager.delegate = self; // you'll need to declare you implement the NSLayoutManagerDelegate protocol
Run Code Online (Sandbox Code Playgroud)

然后覆盖此委托方法:

- (CGFloat)layoutManager:(NSLayoutManager *)layoutManager lineSpacingAfterGlyphAtIndex:(NSUInteger)glyphIndex withProposedLineFragmentRect:(CGRect)rect
{
    return 20; // For really wide spacing; pick your own value
}
Run Code Online (Sandbox Code Playgroud)

其次,iOS 7现在支持NSParagraphStyle的lineSpacing.这给出了更多控制,例如第一行缩进和边界矩形的计算.所以另外......

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.headIndent = 15; // <--- indention if you need it
paragraphStyle.firstLineHeadIndent = 15;

paragraphStyle.lineSpacing = 7; // <--- magic line spacing here!

NSDictionary *attrsDictionary =
@{ NSParagraphStyleAttributeName: paragraphStyle }; // <-- there are many more attrs, e.g NSFontAttributeName

self.textView.attributedText = [[NSAttributedString alloc] initWithString:@"Hello World over many lines!" attributes:attrsDictionary];
Run Code Online (Sandbox Code Playgroud)

FWIW,旧的contentInset方法沿着UITextView的左边缘对齐文本在iOS7下也没用.相反,要删除保证金:

textView.textContainer.lineFragmentPadding = 0;
Run Code Online (Sandbox Code Playgroud)

  • 唯一的问题是你不能用它来使线高*更小* (5认同)
  • +1,非常感谢,你挽救了我的生命:D (2认同)

mxc*_*xcl 25

注意:这在iOS7中不可用:


我发现你可以创建一个重新实现的子类[UITextView styleString]:

@interface UITextView ()
- (id)styleString; // make compiler happy
@end

@interface MBTextView : UITextView
@end
@implementation MBTextView
- (id)styleString {
    return [[super styleString] stringByAppendingString:@"; line-height: 1.2em"];
}
@end
Run Code Online (Sandbox Code Playgroud)

这不是私有API用法:它只是子类化.Apple当然可能不同意(虽然考虑到我们所有人为了定制UIKit外观而习惯于调整所有东西,我觉得这种"私人"用法并不是Apple反对的),但它是如此简单的实现方式这个问题的目标你也可以尝试一下.如果应用程序被拒绝,您可以将(可能很长的)时间用于更困难的解决方案.

  • 这是安全的,我从1.0版开始就在我的一个应用程序中使用过它.现在我的版本是1.0.4,并且所有应用程序都通过了appstore审核! (5认同)
  • 在iOS7中,styleString**不可用** (4认同)

Max*_*ann 19

我们找到的唯一解决方案和我们选择的解决方案:创建自定义字体.听起来很傻,但似乎是唯一现实的方式.


Veg*_*ard 16

在UITextView的Attribute Inspector中,将属性更改TextAttributed(from Plain),然后单击"more"按钮,可以在那里设置行高和间距.

UITextView的属性检查器


use*_*004 10

只有在UITextView上定义了一个定义styleString的类别时,才能使用styleString的UITextView子类覆盖,否则会出现编译错误.例如,在您的UITextView子类中:

#import "SomeDangTextView.h"

@interface UITextView ()

- (id)styleString;

@end

@implementation SomeDangTextView

- (id)styleString {
    return [[super styleString] stringByAppendingString:@"; line-height: 1.5em"];
}

@end
Run Code Online (Sandbox Code Playgroud)


Rap*_*ael 5

这个问题已经有近 10 年历史了,但它是这样解决的:

只需实现以下方法UITextViewDelegate并设置您的属性:

let textViewAttributes: [NSAttributedString.Key:Any] = [
    .font: UIFont.systemFont(ofSize: 15, weight: .medium),
    .foregroundColor: UIColor.black,
    .paragraphStyle: {
        let paragraph = NSMutableParagraphStyle()
        paragraph.lineSpacing = 4
        return paragraph
    }()
]

func textViewDidBeginEditing(_ textView: UITextView) {
    textView.typingAttributes = textViewAttributes
}
Run Code Online (Sandbox Code Playgroud)

添加这些属性非常重要,textViewDidBeginEditing因为每次文本选择更改时字典都会重置。更多信息可以在官方文档中找到。