简体   繁体   English

替换文本后防止 NSTextView 自动滚动到顶部

[英]Prevent NSTextView auto scroll to top after replace text

I'm struggling with this seems to be simple problem, but have not found the good fix yet:我正在努力解决这个似乎很简单的问题,但还没有找到好的解决方法:

I have a NSTextView inside NSScrollView, textView is non-editable, the whole textView stringValue is replaced after every 2s.我在 NSScrollView 里面有一个 NSTextView,textView 是不可编辑的,整个 textView stringValue 在每 2 秒后被替换。

It works fine when the textView height is less than scrollView height, but when it's longer then the scrollView will always automatically scroll back to top after each text replace.当 textView 高度小于 scrollView 高度时它工作正常,但当它更长时,scrollView 将在每次替换文本后自动滚动回顶部。 I'd want it to keep the same offset after update.我希望它在更新后保持相同的偏移量。

My current implement, it works but it flickering due to manual scrolling, hope to find a way that can keep the offset without flickering, not sure if there's any config that can do it:我目前的工具,它可以工作,但由于手动滚动而闪烁,希望找到一种可以保持偏移不闪烁的方法,不确定是否有任何配置可以做到:

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))];
      });
}

After checking some similar iOS question, I found a way to do this, the point is not replacing the text using binding or set it via textView.string :在检查了一些类似的 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)];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM