我建设有自定义控件一个基本的文本编辑器。对于我的文字对齐控制,我需要支付两个用户场景:NSTextView撤销/重做属性发生变化时(不是第一个响应者)
文本视图是第一个响应者 - 使段属性更改
textView.rangesForUserParagraphAttributeChange
文本视图是不是第一个响应者 - 使段落属性更改为全文本范围。
这里的方法:
- (IBAction)changedTextAlignment:(NSSegmentedControl *)sender
{
NSTextAlignment align;
// ....
NSRange fullRange = NSMakeRange(0, self.textView.textStorage.length);
NSArray *changeRanges = [self.textView rangesForUserParagraphAttributeChange];
if (![self.mainWindow.firstResponder isEqual:self.textView])
{
changeRanges = @[[NSValue valueWithRange:fullRange]];
}
[self.textView shouldChangeTextInRanges:changeRanges replacementStrings:nil];
[self.textView.textStorage beginEditing];
for (NSValue *r in changeRanges)
{
@try {
NSDictionary *attrs = [self.textView.textStorage attributesAtIndex:r.rangeValue.location effectiveRange:NULL];
NSMutableParagraphStyle *pStyle = [attrs[NSParagraphStyleAttributeName] mutableCopy];
if (!pStyle)
pStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[pStyle setAlignment:align];
[self.textView.textStorage addAttributes:@{NSParagraphStyleAttributeName: pStyle}
range:r.rangeValue];
}
@catch (NSException *exception) {
NSLog(@"%@", exception);
}
}
[self.textView.textStorage endEditing];
[self.textView didChangeText];
// ....
NSMutableDictionary *typingAttrs = [self.textView.typingAttributes mutableCopy];
NSMutableParagraphStyle *pStyle = typingAttrs[NSParagraphStyleAttributeName];
if (!pStyle)
pStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[pStyle setAlignment:align];
[typingAttrs setObject:NSParagraphStyleAttributeName forKey:pStyle];
self.textView.typingAttributes = typingAttrs;
}
所以这两种情况下正常工作......但撤销/重做时的变化在“不先响应”方案应用于不起作用。撤销管理器将某些东西压入堆栈(即在编辑菜单中可以使用撤消),但调用撤消不会改变文本。它所做的只是显示全文的范围。
如何适当地改变文本视图属性,以便撤销/重做的作品,无论视图是否是第一reponder与否?
预先感谢您!
谢谢@bhaller。我尝试了你的建议,但结果相同。最终,这似乎是在之后改变'typingAttributes'的对齐方式的问题(请参阅我的答案)。真的很感谢你的见解! –
有趣。键入属性 - 我没有看到即将到来的。 : - > – bhaller
Lolz,我刚刚发现它是我的代码中的一个错字。不是bug! –