【问题标题】:Prevent NSTextView auto scroll to top after replace text替换文本后防止 NSTextView 自动滚动到顶部
【发布时间】:2021-10-24 14:03:42
【问题描述】:

我正在努力解决这个似乎很简单的问题,但还没有找到好的解决方法:

我在 NSScrollView 里面有一个 NSTextView,textView 是不可编辑的,整个 textView 的 stringValue 每 2s 被替换一次。

当 textView 高度小于 scrollView 高度时它可以正常工作,但是当它更长时,scrollView 将始终在每次文本替换后自动滚动回顶部。我希望它在更新后保持相同的偏移量。

我目前的实现,它可以工作,但是由于手动滚动而闪烁,希望找到一种可以保持偏移而不闪烁的方法,不知道是否有任何配置可以做到:

CGFloat offset = self.scrollView.documentVisibleRect.origin.y;
self.newText = .....; // Update the textView string via binding
if (offset > 0) {
      CGFloat maxHeight = fabs(self.scrollView.documentView.frame.size.height - self.scrollView.frame.size.height) + 2;
      dispatch_async(dispatch_get_main_queue(), ^{
            [self.scrollView.documentView scrollPoint:CGPointMake(0, MIN(offset, maxHeight))];
      });
}

【问题讨论】:

标签: swift objective-c macos nstextview nsscrollview


【解决方案1】:

在检查了一些类似的iOS问题后,我找到了一种方法,关键不是使用绑定替换文本或通过textView.string设置它:

NSRange selectedRange = self.textView.selectedRange;
[self.textView.textStorage beginEditing];
NSRange rangeToReplace = NSMakeRange(0, self.textView.textStorage.string.length);
[self.textView.textStorage replaceCharactersInRange:rangeToReplace withString:newText];
[self.textView.textStorage endEditing];

// This is to keep the selected text
if(selectedRange.location != NSNotFound && NSMaxRange(selectedRange) <= rangeToReplace.length) {
   [self.textView setSelectedRange:NSMakeRange(selectedRange.location, selectedRange.length)];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多