如何在UITextView中设置边距(内边距)?

58

我有一个用于文本编辑的UITextView。默认情况下,它在文本周围有一个小边距。我想将该边距增加几个像素。

contentInset属性提供了边距,但它不会改变文本的“换行宽度”。文本仍然以相同的宽度换行,额外的“边距”只会导致视图水平滚动。

有没有办法让指定宽度的UITextView显示出具有较窄“换行宽度”的文本吗?


有关此问题的更详细答案,请参阅以下答案:https://dev59.com/lG865IYBdhLWcg3wnf5t?page=2&tab=oldest#tab-top - Bhavin_m
9个回答

122

iOS 7 开始,您可以使用 textContainerInset 属性:

Objective-C

textView.textContainerInset = UIEdgeInsetsMake(0, 20, 0, 20);

Swift

textView.textContainerInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)

3
还可以只添加左右的_textContainerInsets_。 textView.textContainerInset.left = 20 textView.textContainerInset.right = 20 - Abduhafiz

35

如果你只是在开发iOS 6,那么在一番折腾之后,我找到了另一个解决方案。使用contentInset设置顶部和底部边距:

在这个问题上摸索了一段时间后,我发现如果你只在iOS 6上进行开发,可以通过contentInset来设置顶部和底部的边距,从而得到另一个解决方案:

textView = [[UITextView alloc] init];
textView.contentInset = UIEdgeInsetsMake(20.0, 0.0, 20.0, 0.0);

对于左右边距,请勿直接添加纯文本,而是使用已正确设置左右缩进的 NSMutableParagraphStyleNSAttributedString

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.headIndent = 20.0;
paragraphStyle.firstLineHeadIndent = 20.0;
paragraphStyle.tailIndent = -20.0;

NSDictionary *attrsDictionary = @{NSFontAttributeName: [UIFont fontWithName:@"TrebuchetMS" size:12.0], NSParagraphStyleAttributeName: paragraphStyle};
textView.attributedText = [[NSAttributedString alloc] initWithString:myText attributes:attrsDictionary];

这将为您提供一个带有20像素填充且可以正常滚动的UITextView(在我的情况下是从变量myText中获取的文本)。


10

试一试

UIBezierPath* aObjBezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 20, 20)];
txtView.textContainer.exclusionPaths  = @[aObjBezierPath];

7

您可以使用较小的UITextView,并将UIView放在背景中以模拟填充。

+----------+
|          | <-- UIView (as background)
|   +--+   |
|   |  | <---- UITextView
|   |  |   |
|   +--+   |
|          |
+----------+

1
是的,这就是我现在正在做的。对于侧边距来说还可以,但顶部边距存在问题。从用户的角度来看,在滚动时文本在顶部被“截断”,因为文本只在UITextView中呈现。 - strawtarget
5
用这种方式,你无法正确显示垂直滚动条。 - an0
textView.clipsToBounds = NO 进行设置将“修复”顶部截断的问题,但这种方式只是部分解决。当然,这不会帮助正确显示垂直滚动条。 - villapossu

3
如果你想从一个方向设置 padding,可以使用下面的代码:
 textView.contentInset.left = 5 //For left padding
 textView.contentInset.right = 5 //For right padding
 textView.contentInset.top = 5 //For top padding
 textView.contentInset.bottom = 5 //For bottom padding

1
感谢您的建议。 在开发macOS / OSX应用程序时,我遇到了这个问题,并最终得出了以下解决方案:
textView.textContainerInset = NSSize(width: 20, height: 20); //Sets margins

1

这对我很有效。通过更改textView的contentInset和frame inset/position来获得正确的填充和换行。然后更改textView的边界,以防止水平滚动。每次选择和更改文本时,还需要重置填充。

- (void)setPadding
{
    UIEdgeInsets padding = UIEdgeInsetsMake(30, 20, 15, 50);

    textView.contentInset = padding;

    CGRect frame = textView.frame;

    // must change frame before bounds because the text wrap is reformatted based on frame, don't include the top and bottom insets
    CGRect insetFrame = UIEdgeInsetsInsetRect(frame, UIEdgeInsetsMake(0, padding.left, 0, padding.right));

    // offset frame back to original x
    CGFloat offsetX = frame.origin.x - (insetFrame.origin.x - ( padding.left + padding.right ) / 2);
    insetFrame = CGRectApplyAffineTransform(insetFrame, CGAffineTransformMakeTranslation(offsetX, 0));

    textView.frame = insetFrame;

    textView.bounds = UIEdgeInsetsInsetRect(textView.bounds, UIEdgeInsetsMake(0, -padding.left, 0, -padding.right));

    [textView scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];
}

-(void)textViewDidChangeSelection:(UITextView *)textView
{
    [self setPadding];
}

-(void)textViewDidChange:(UITextView *)textView
{
    [self setPadding];
}

@Nate,这对我没有起作用。TextView 仍然水平滚动,内容插入溢出文本视图的框架。 - GoGreen

1

0

Swift + iOS 12: 一种不同的方法

将左侧和右侧的填充设置到我们的UITextView上,当输入超过9行文本时,文本会消失。使用@rajesh的解决方案有助于解决此问题:

确保在文本更改和设备旋转时调用该方法。

    /// Updates the left + right padding of the current text view.
    /// -> leftRightPadding value = 11.0
    func updateLeftRightPadding() {
        let leftPadding = UIBezierPath(rect: .init(x: 0.0, y: 0.0,
                                       width: leftRightPadding, height: contentSize.height))
        let rightPadding = UIBezierPath(rect: .init(x: frame.width - leftRightPadding, y: 0.0,
                                        width: 11, height: contentSize.height))
        textContainer.exclusionPaths = [leftPadding, rightPadding]
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接