我在后台运行了NSTask
(设置了NSPipe
)我希望在NSTextView
中输出内容,因为它们正在进入(output
)。
我正在使用的代码是:
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)];
问题:
NSTextView
位于工作表上,当鼠标指针位于其他位置而不是悬停在NSTextView
NSTextView
的颜色/插入颜色 /等,但这似乎不适用于新插入的文字?NSTextView
附加(+滚动)方式是什么?谢谢!
答案 0 :(得分:8)
请记住,用户界面元素(包括NSTextView
)在主线程上发挥作用。如果您尝试向文本视图添加信息,那么您最好这样做。方法如下:
[[output textStorage] performSelectorOnMainThread:@selector(appendAttributedString:)
withObject:str
waitUntilDone:YES];
我会谈到你的第三点,但坦率地说,这是我仍然非常学生的事情。
为了解决你的第四点,看起来你已经弄清楚了;只需合并你的追加和滚动动作。但就像更改textStorage
的内容一样,您希望确保在主线程上执行此操作。由于-scrollRangeToVisible:
没有为其参数提供对象,因此您必须以不同的方式执行此操作:
dispatch_async(dispatch_get_main_queue(), ^{
[output scrollRangeToVisible:NSMakeRange([[output string] length], 0)];
});
尽管我的第一个例子,您也可以将您的电话拨打到-appendAttributedString:
内:
dispatch_async(dispatch_get_main_queue(), ^{
[[output textStorage] appendAttributedString:str];
[output scrollRangeToVisible:NSMakeRange([[output string] length], 0)];
});
答案 1 :(得分:0)
关于附加到NSTextView的推荐方法:你在appendAttributedString:中表现得很好,但是建议在shouldChangeTextInRange中设置它,然后是beginEditing,appendAttributedString,最后是endEditing:
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:会导致大量闪烁,当你向下移动“范围”时它也会逐渐变慢。
快速而肮脏的方式可能是这样的:
- (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做所有的计算工作。 我这样做,因为无论如何我的计算失败了(Apple和其他人使用visRect / docRect坐标建议的那些,产生了不可靠的结果)。 reflectScrolledClipView也很重要;它会更新滚动条,使其具有正确的比例和位置。
您可能还会发现滚动发生时很有趣。如果是这样,请同时订阅NSViewBoundsDidChangeNotification和NSViewFrameDidChangeNotification。当其中一个出现时,滚动条位置很可能发生变化(调查[textView visibleRect]和[textView bounds])。
我发现你的文字属性也有问题。我也是这么久了。 我发现附加一个属性字符串会有很多帮助,但对于输入的文本来说仍然不够。 ..然后我发现了关于打字的属性。 在设置NSTextView时,例如在-awakeFromNib中,您可以从以下内容中选择您喜欢的内容......
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并选项 - 双击它,然后您将看到更多属性(您也可以命令双击;这将带您到头文件中的定义。)