【发布时间】:2015-10-13 15:12:26
【问题描述】:
我正在构建一个带有自定义控件的基本文本编辑器。对于我的文本对齐控件,我需要涵盖两个用户场景:
文本视图是第一响应者 - 将段落属性更改为
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;
}
所以这两种情况都可以正常工作...但是当更改应用于“非第一响应者”情况时,撤消/重做不起作用。撤消管理器将某些内容推入其堆栈(即撤消在编辑菜单中可用),但调用撤消不会更改文本。它所做的只是明显地选择整个文本范围。
我如何适当地更改文本视图属性,以便无论视图是否是第一个响应者,撤消/重做都能正常工作?
提前谢谢你!
【问题讨论】:
标签: macos cocoa nstextview nsundomanager