【问题标题】:Justify last line of UITextView对齐 UITextView 的最后一行
【发布时间】:2020-06-03 16:58:52
【问题描述】:

我正在写一个类似项目的书。您可以滚动浏览多个页面上的段落列表。我为每一页创建单独的UITextView,并将其设置为合理的,以创建类似书本的体验。不幸的是,UITextView 的最后一行是不合理的(因为我对每一页都使用了新的UITextView)。所以事实上UITextView 的行为是正确的。但是当我的段落在下一页继续时,我希望它通过证明最后一行来表达这一点。我正在使用UITextView 为用户提供选择和复制部分文本的选项。

This is how it looks now.

This is what is expected.

【问题讨论】:

  • 添加你目前尝试过的代码。
  • @PGDev 我找不到任何只会影响最后一行的代码。不知道如何处理它。我只能通过设置 textAlignment 属性来影响其他行。

标签: objective-c swift uitextview justify


【解决方案1】:

我在 UITextView 上添加了一个类别来执行最后一行所需的计算。这可以是单独的 .h/.m 文件,也可以放在需要使用它的 .m 文件的顶部。请注意,这对属性文本和 textContainer 属性起作用。即使您仅在 UITextView 上设置 text 属性,也会设置属性文本属性(从 iOS7 开始)。 textContainer 属性定义 UITextView 将呈现其文本的区域的大小,但如果您使用约束来布局 UITextView,您可能需要稍微不同。

@interface UITextView (LastLineRange)

- (NSRange) lastLineRange;

@end

@implementation UITextView (LastLineRange)

- (NSRange)lastLineRange
{
    // calculate the bounds for the text rendered in the UITextView
    CGSize textSize = [self.attributedText boundingRectWithSize:self.textContainer.size
                                                        options:NSStringDrawingUsesLineFragmentOrigin
                                                        context:nil].size;

    // we care about the last line, so get the start and end points along the bottom of the bounds
    UITextPosition* start = [self characterRangeAtPoint:CGPointMake(0, textSize.height)].start;
    UITextPosition* end = [self characterRangeAtPoint:CGPointMake(textSize.width, textSize.height)].end;

    // turn the text positions into indices we can make a range with
    NSInteger startLoc = [self offsetFromPosition:self.beginningOfDocument
                                       toPosition:start];

    // this should not be 'endOfDocument', but the end that we calculated above,
    // since this represents the end of the visible text
    NSInteger endLoc = [self offsetFromPosition:start
                                     toPosition:end];

    return NSMakeRange(startLoc, endLoc);
}

@end

这就是我使用类别获取最后一行并对其应用右对齐段落样式的方式。我试图添加 cmets 以明确发生了什么。我只是粗略地制作了实际的 UITextView,所以它不像你的例子那么漂亮,但应该给你这个想法。

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIFont* font = [UIFont systemFontOfSize:20.0];

    // used for the main, left-aligned text
    NSMutableParagraphStyle* pStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    pStyle.lineBreakMode = NSLineBreakByWordWrapping;
    pStyle.alignment = NSTextAlignmentLeft;

    // used for the last line, which will be right-aligned
    NSMutableParagraphStyle* lastStyle = [pStyle mutableCopy];
    lastStyle.alignment = NSTextAlignmentRight;

    CGRect pageFrame = CGRectMake(self.view.frame.size.width / 4.0,
                                  50.0,
                                  self.view.frame.size.width / 2.0,
                                  self.view.frame.size.height / 2.0);

    UITextView* page = [[UITextView alloc] initWithFrame:pageFrame
                                            textContainer:nil];

    page.scrollEnabled = false;
    page.editable = false;

    // attributes for main text
    NSDictionary* lAlignedAttrs = @{
                                    NSFontAttributeName : font,
                                    NSParagraphStyleAttributeName : pStyle
                                   };

    // attributes for the last line of text
    NSDictionary* rAlignedAttrs = @{
                                    NSFontAttributeName : font,
                                    NSParagraphStyleAttributeName : lastStyle,
                                    // only added this to highlight the last line changes
                                    NSForegroundColorAttributeName : [UIColor redColor]
                                   };

    // needs to be mutable, so we can set attributes at certain ranges
    NSMutableAttributedString* text1 = [[NSMutableAttributedString alloc] initWithString:text
                                                                    attributes:lAlignedAttrs];

    // now set the attributed text as content for the UITextView, since
    // we will use the category for finding the last line
    page.attributedText = text1;

    // here, we ensure that the last line will be considered a new paragraph
    // so the paragraph style changes we make will take effect
    NSInteger insertionIndex = page.lastLineRange.location;
    if ( [text1.string characterAtIndex:insertionIndex] != '\n' )
    {
        [text1 insertAttributedString:[[NSAttributedString alloc] initWithString:@"\n"]
                              atIndex:insertionIndex];
    }

    // apply right-aligned paragraph style over the range of the last line
    [text1 setAttributes:rAlignedAttrs
                   range:page.lastLineRange];

    // we have altered the attributed text, so need to set the new text
    // as the content for the UITextView
    page.attributedText = text1;

    [self.view addSubview:page];
}


@end

这是我用这个实现的:

【讨论】:

  • 嗨,我刚刚编辑了我的问题以包含预期内容。希望这会让它更清楚。
  • @svojtko 我编辑显示我为你工作的结果。如果我误解了您的意思,请告诉我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-01
相关资源
最近更新 更多