0
私は "ローリングログ"と呼ばれるものを表示しているNSTextViewを持っています。新しいAttributedString
はちょうど約毎秒追加されています。私がしたいのは、文字列が特定の長さ、または特定の数の行に当たった場合、NSTextView
の先頭から切り捨てることです。これは、表示されたログが1トンのメモリを消費しないようにするためです。自動スクロールのテキストの長さを制限するNSTextView
これについてはどうすればよいですか?私はいくつかのコードを持っていますが、それは私が期待するように、特に自動スクロールの周りに動作するようには見えません。
期待される動作:
- 必要に応じて引き出し線を取り外します(これは線や文字の数である場合、私は本当に最も簡単な方、気にしません)。
- ビューがスクロールアップされていない場合は、自動的にスクロールします(ユーザーが現在スクロールしている場合は、スクロールしてもスクロールしません)。
コード:
- (void)append:(TextTag*)text toTextView:(MyNSTextView *) textView {
dispatch_async(dispatch_get_main_queue(), ^{
NSAttributedString *attr = [self stringFromTag:text];
NSScroller *scroller = [[textView enclosingScrollView] verticalScroller];
double autoScrollToleranceLineCount = 3.0;
NSUInteger lines = [self countLines:[textView string]];
double scrolled = [scroller doubleValue];
double scrollDiff = 1.0 - scrolled;
double percentScrolled = autoScrollToleranceLineCount/lines;
BOOL shouldScrollToBottom = scrollDiff <= percentScrolled;
[textView.textStorage beginEditing];
if (lines >= 10000) {
NSRange removeRange = [self getRemovalRange:textView.string];
[textView.textStorage deleteCharactersInRange:removeRange];
}
[[textView textStorage] appendAttributedString:attr];
[textView.textStorage endEditing];
if(shouldScrollToBottom) {
[textView scrollRangeToVisible:NSMakeRange([[textView string] length], 0)];
}
});
}
- (NSRange)getRemovalRange:(NSString *)s {
NSUInteger numberOfLines, index, stringLength = [s length];
for (index = 0, numberOfLines = 0; index < stringLength;
numberOfLines++) {
index = NSMaxRange([s lineRangeForRange:NSMakeRange(index, 0)]);
if (numberOfLines >= 100) {
break;
}
}
return NSMakeRange(0, index);
}
- (NSUInteger) countLines:(NSString *)s {
NSUInteger numberOfLines, index, stringLength = [s length];
for (index = 0, numberOfLines = 0; index < stringLength;
numberOfLines++) {
index = NSMaxRange([s lineRangeForRange:NSMakeRange(index, 0)]);
}
return numberOfLines;
}
私は何か似たようなことをしました。スクロールは 'self performSelector:@selector(scrollProgressTextViewToEnd)withObject:nil afterDelay:0];'のようなrunloopの次の反復で実行されます。 – Willeke
@Willeke最初に行って、それは動作しているようです!それを一日中混乱させてしまいますが、それを答えとして追加して、私はあなたに信用を与えることができますか? –
それを数時間試した後も、時にはスクロールしないようです。 =/ –