NSLineBreakByTruncatingTail 在 NSTextView 中设置为段落样式时滚动文本

发布于 2024-12-27 21:50:55 字数 2754 浏览 1 评论 0 原文

我有一个 NSTextView,它应该是固定大小的。当文本到达底线和指定框架的右边缘时,我需要设置 NSLineBreakByTruncatingTail 以便向用户显示椭圆符号并禁用进一步键入。 当我通过在 NSTextViewtextStorage 上设置段落样式来执行此操作时,文本向上滚动,我只看到最后一行带有椭圆符号。我的问题是如何防止 NSTextView 在更改其 lineBreakMode 时滚动?

谢谢, Nava

编辑:(添加屏幕截图)之前:

之后:

在此处输入图像描述

现在这是执行此操作的代码:

- (void)textDidChange:(NSNotification *)notification
{
    NSString *text = [textView string];

    CGFloat width, height;
    NSRect  newFrame = self.frame;

    width = round([text widthForHeight:newFrame.size.height font:textView.font]);

    height = round([text heightForWidth:newFrame.size.width font:textView.font]);
    if (height > newFrame.size.height && width > newFrame.size.width) {
        NSTextContainer *textContainer = textView.textContainer;
        [textContainer setWidthTracksTextView:NO];
        [textContainer setHeightTracksTextView:NO];
        [textView setHorizontallyResizable:NO];
        [textView setVerticallyResizable:NO];
        [textView setAutoresizingMask:NSViewNotSizable];
        [textView setLineBreakMode:NSLineBreakByTruncatingTail];
    } 
}

函数 widthForHeightheightForWidth 是一些第三方补充,效果很好。问题出在我设置 NSLineBreakByTruncatingTail 时发生的突然滚动。 这是设置换行模式的函数(也是第三方添加 - 来自一位优秀的开发人员(不记得他的名字)):

- (void)setLineBreakMode:(NSLineBreakMode)lineBreakMode {
    NSDictionary* curAttributes = [[self textStorage] attributesAtIndex:0
                                                              effectiveRange:NULL];

    NSParagraphStyle *currentStyle = [curAttributes objectForKey:NSParagraphStyleAttributeName];

    if (currentStyle.lineBreakMode != lineBreakMode) {

        NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy] ;
        [paragraphStyle setLineBreakMode:lineBreakMode] ;       
        NSMutableDictionary* attributes = [[[self textStorage] attributesAtIndex:0
                                                                  effectiveRange:NULL] mutableCopy] ;

        [attributes setObject:paragraphStyle
                       forKey:NSParagraphStyleAttributeName] ;
        [paragraphStyle release] ;
        NSAttributedString* attributedString = [[NSAttributedString alloc] initWithString:[self string]
                                                                               attributes:attributes] ;
        [attributes release] ;
        [[self textStorage] setAttributedString:attributedString] ;
        [attributedString release] ;

    }
}

I have a NSTextView, which is supposed to be fixed size. When the text comes to the bottom line and to the right edge of the designated frame I need to set the NSLineBreakByTruncatingTail in order to present user with elliptic signs and disable further typing.
When I do this through setting a paragraph style on textStorage of NSTextView the text scrolls up and I see only the last line with elliptic signs in the end. My question is how to prevent NSTextView from scrolling when changing its lineBreakMode?

Thanks,
Nava

EDIT: (added screenshots) Before:

enter image description here

After:

enter image description here

Now here's the code that does it:

- (void)textDidChange:(NSNotification *)notification
{
    NSString *text = [textView string];

    CGFloat width, height;
    NSRect  newFrame = self.frame;

    width = round([text widthForHeight:newFrame.size.height font:textView.font]);

    height = round([text heightForWidth:newFrame.size.width font:textView.font]);
    if (height > newFrame.size.height && width > newFrame.size.width) {
        NSTextContainer *textContainer = textView.textContainer;
        [textContainer setWidthTracksTextView:NO];
        [textContainer setHeightTracksTextView:NO];
        [textView setHorizontallyResizable:NO];
        [textView setVerticallyResizable:NO];
        [textView setAutoresizingMask:NSViewNotSizable];
        [textView setLineBreakMode:NSLineBreakByTruncatingTail];
    } 
}

Functions widthForHeight and heightForWidth are some 3rd party additions, which work well. The problem is in this sudden scroll that happens when I set NSLineBreakByTruncatingTail.
Here's the function, that sets the line break mode (also 3rd party addition - from a nice developer (don't remember his name)):

- (void)setLineBreakMode:(NSLineBreakMode)lineBreakMode {
    NSDictionary* curAttributes = [[self textStorage] attributesAtIndex:0
                                                              effectiveRange:NULL];

    NSParagraphStyle *currentStyle = [curAttributes objectForKey:NSParagraphStyleAttributeName];

    if (currentStyle.lineBreakMode != lineBreakMode) {

        NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy] ;
        [paragraphStyle setLineBreakMode:lineBreakMode] ;       
        NSMutableDictionary* attributes = [[[self textStorage] attributesAtIndex:0
                                                                  effectiveRange:NULL] mutableCopy] ;

        [attributes setObject:paragraphStyle
                       forKey:NSParagraphStyleAttributeName] ;
        [paragraphStyle release] ;
        NSAttributedString* attributedString = [[NSAttributedString alloc] initWithString:[self string]
                                                                               attributes:attributes] ;
        [attributes release] ;
        [[self textStorage] setAttributedString:attributedString] ;
        [attributedString release] ;

    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文