首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >附加到NSTextView

附加到NSTextView
EN

Stack Overflow用户
提问于 2012-04-03 12:12:48
回答 2查看 3.9K关注 0票数 2

我在后台运行了一个NSTask (设置了一个NSPipe ),我想在NSTextView (output)中输出内容。

我使用的代码是:

代码语言:javascript
复制
NSMutableAttributedString* str = [[NSMutableAttributedString alloc] initWithString:s];
//[str addAttribute:NSForegroundColorAttributeName value:[NSColor whiteColor] range:NSMakeRange(0, [str length])];

[[output textStorage] appendAttributedString:str];

[output scrollRangeToVisible:NSMakeRange([[output string] length], 0)];

问题:

当有大量数据附加时,视图似乎是"flashing"...。当鼠标指针在NSTextView

  • Why上方悬停时,似乎没有任何内容出现在NSTextView

  • Why上,当鼠标指针悬停在NSTextView

  • Why上方时,不工作的NSTextView似乎没有出现,尽管我已经设置了NSTextView颜色/插入颜色/etc,但这似乎不适用于新插入的文本?

  • 建议的在NSTextView

上追加(+滚动)的方法是什么?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-04 00:08:14

请记住,用户界面元素(这包括NSTextView )在主线程上执行它们的魔术。如果您试图将信息添加到文本视图中,那么最好在那里进行。下面是操作步骤:

代码语言:javascript
复制
[[output textStorage] performSelectorOnMainThread:@selector(appendAttributedString:) 
                                       withObject:str 
                                    waitUntilDone:YES];

我想谈谈你的第三点,但坦率地说,我仍然是个学生。

为了解决第四点,您似乎已经解决了这一问题;只需将附加操作和滚动操作结合起来即可。但是,就像更改textStorage的内容一样,您希望确保在主线程上这样做。由于-scrollRangeToVisible:不以对象作为其参数,所以您必须做一些不同的操作:

代码语言:javascript
复制
dispatch_async(dispatch_get_main_queue(), ^{
    [output scrollRangeToVisible:NSMakeRange([[output string] length], 0)];
});

尽管有第一个例子,您也可以将对-appendAttributedString:的调用放在该块中:

代码语言:javascript
复制
dispatch_async(dispatch_get_main_queue(), ^{
    [[output textStorage] appendAttributedString:str];
    [output scrollRangeToVisible:NSMakeRange([[output string] length], 0)];
});
票数 8
EN

Stack Overflow用户

发布于 2013-02-15 23:38:38

关于添加到NSTextView的推荐方法:您在appendAttributedString:方面做得很好,但建议在shouldChangeTextInRange中屏蔽它,然后是beginEditing、appendAttributedString,最后是endEditing::

代码语言:javascript
复制
textStorage = [textView textStorage];
if([textView shouldChangeTextInRange:range replacementString:string])
{
    [textStorage beginEditing];
    [textStorage replaceCharactersInRange:range withAttributedString:attrStr];
    // or if you've already set up the attributes (see below)...
    // [textStorage replaceCharactersInRange:range withString:str];
    [textStorage endEditing];
}

我强烈建议将scrollRangeToVisible:替换为scrollToPoint:,因为scrollRangeToVisible:会引起大量闪烁,而且随着您“向下移动”,它也会逐渐变慢。

一种快速而肮脏的方式可能是这样的:

代码语言:javascript
复制
- (void)scrollToBottom
{
    NSPoint     pt;
    id          scrollView;
    id          clipView;

    pt.x = 0;
    pt.y = 100000000000.0;

    scrollView = [self enclosingScrollView];
    clipView = [scrollView contentView];

    pt = [clipView constrainScrollPoint:pt];
    [clipView scrollToPoint:pt];
    [scrollView reflectScrolledClipView:clipView];
}

我让constrainScrollPoint做所有的计算工作。我这么做是因为我的计算失败了(使用visRect/docRect坐标的Apple和其他人建议的计算结果不可靠)。reflectScrolledClipView也很重要;它更新滚动条,使其具有正确的比例和位置。

您可能还会发现,了解滚动发生的时间也很有趣。如果是这样,请同时订阅NSViewBoundsDidChangeNotification和NSViewFrameDidChangeNotification。当其中一个发生时,滚动条的位置最有可能发生变化(调查textView visibleRect和textView边界)。

我看你在文本属性上也有问题。我也做了很长一段时间。我发现附加属性字符串会有很大帮助,但仍然不足以输入文本。..Then我发现了typingAttributes的事。在设置NSTextView时,例如在-awakeFromNib中,您可以从以下内容中选择您喜欢的内容.

代码语言:javascript
复制
NSMutableParagraphStyle *paragraphStyle;
float                   characterWidth;
NSFont                  *font;
uint32_t                tabWidth;
NSMutableDictionary     *typingAttributes;

tabWidth = 4;
font = [NSFont fontWithName:@"Monaco" size:9.0];
paragraphStyle = [[textView defaultParagraphStyle] mutableCopy];
if(NULL == paragraphStyle)
{
    paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    // or maybe:
    // paragraphStyle = [NSParagraphStyle new];
}
characterWidth = [[font screenFontWithRenderingMode:NSFontDefaultRenderingMode] advancementForGlyph:(NSGlyph)' '].width;
[paragraphStyle setDefaultTabInterval:(characterWidth * (float) tabWidth];
[paragraphStyle setTabStops:[NSArray array]];
typingAttributes = [[textView typingAttributes] mutableCopy];
if(NULL == typingAttributes)
{
    typingAttributes = [NSMutableDictionary new];
}
[typingAttributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
[typingAttributes setObject:font forKey:NSFontAttributeName];
[textView setTypingAttributes:attributes];

它比您可能需要的要多得多,但是它显示了如何设置字体、选项卡宽度和输入属性。NSForegroundColorAttributeName对您可能也很感兴趣(以及其他一些属性,在Xcode中键入NSForegroundColorAttributeName和选项-双击它,然后您将看到更多的属性(您也可以命令双击;这将带您进入头文件中的定义)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9993008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档