问题描述
|
在我正在使用的应用程序中,用户输入纯文本,然后该应用程序通过将其转换为NSAttributedString来重新格式化文本并显示它。这一切都是实时发生的。
目前,我正在NSTextView的textDidChange委托方法上执行以下操作:
- (void)textDidChange:(NSNotification *)notification {
// saving the cursor position
NSInteger insertionPoint = [[[self.mainTextView selectedRanges] objectAtIndex:0] rangeValue].location;
// this grabs the text view\'s contact as plain text
[self updateContentFromTextView];
// this creates an attributed strings and displays it
[self updateTextViewFromContent];
// resetting the cursor position
self.mainTextView.selectedRange = NSMakeRange(insertionPoint,0);
}
尽管这通常可以正常工作,但并不理想。文本似乎眨了眨眼(您特别在拼写错误下的红点上注意到了它),并且当光标先前位于可见矩形的边缘之一附近时,滚动位置将重置。就我而言,这是非常不希望的副作用。
所以我的问题是:是否有更好的方法来做我想做的事情?
解决方法
我认为您对ѭ1的工作原理有些误解。用户从不输入“纯字符串” ,,1,的数据存储始终是always3 always对象,它是
NSMutableAttributedString
的子类。
您需要做的是将属性添加/删除到用户正在编辑的现有属性字符串中,而不是替换整个字符串。
您也不应该在‑textDidChange:
委托方法中对字符串进行更改,因为从该方法更改字符串可能会导致另一个更改通知。
相反,您应该实现委托方法“ 6”。每当文本更改时,就会调用此方法。然后,您可以像这样修改字符串:
- (void)textStorageDidProcessEditing:(NSNotification*)notification
{
//get the text storage object from the notification
NSTextStorage* textStorage = [notification object];
//get the range of the entire run of text
NSRange aRange = NSMakeRange(0,[textStorage length]);
//for example purposes,change all the text to yellow
//remove existing coloring
[textStorage removeAttribute:NSForegroundColorAttributeName range:aRange];
//add new coloring
[textStorage addAttribute:NSForegroundColorAttributeName
value:[NSColor yellowColor]
range:aRange];
}