我最终的解决方案是将空间替换为具有调整宽度的空白图像(空白)。
基本组成:
a) 用空格代替空格的方法
b) 用空格代替空格的方法
c) NSValueTransformer 为 NSTextView 做 (a) 为transformedValue 和 (b) 为reverseTransformedValue
d) NSTextViewDelegate 在文本更改时执行 (a) 操作
e) 子类 NSTextView 在发送到粘贴板之前对复制或剪切的文本执行 (b) 操作
f) 分配给步进器以更改尺寸的操作
每个部分的代码如下:
a) AppDelegate方法用空格替换空格
- (NSAttributedString * ) replaceSpacesWithBlanks:(NSString *)replaceString {
CGFloat imageWidth = [[NSUserDefaults standardUserDefaults] integerForKey:@"wordSpacing"];
NSImage * pic = [[NSImage alloc] initWithSize:NSMakeSize(imageWidth, 1.0f)];
NSTextAttachmentCell *attachmentCell = [[NSTextAttachmentCell alloc] initImageCell:pic];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
[attachment setAttachmentCell: attachmentCell ];
NSAttributedString *replacementString = [NSAttributedString attributedStringWithAttachment: attachment];
NSMutableAttributedString *mutableString = [[NSMutableAttributedString alloc] initWithString:replaceString];
NSRange range = [[mutableString string] rangeOfString:@" "];
while (range.location != NSNotFound) {
[mutableString replaceCharactersInRange:range withAttributedString:replacementString];
range = [[mutableString string] rangeOfString:@" "];
}
return [[NSAttributedString alloc] initWithAttributedString: mutableString];
}
b) AppDelegate方法用空格替换空格
- (NSString * ) replaceBlanksWithSpaces:(NSAttributedString *)replaceAttributedString {
NSMutableAttributedString * mutAttrString = [[NSMutableAttributedString alloc] initWithAttributedString:replaceAttributedString];
for (int index = 0; index < mutAttrString.length; index += 1) {
NSRange theRange;
NSDictionary * theAttributes = [mutAttrString attributesAtIndex:index effectiveRange:&theRange];
NSTextAttachment *theAttachment = [theAttributes objectForKey:NSAttachmentAttributeName];
if(theAttachment != NULL) {
[mutAttrString replaceCharactersInRange:theRange withString:@" "];
}
}
return mutAttrString.string;
}
c) NSValueTransformer,用于 NSTextView 将transformedValue 的空格替换为空格,并将reverseTransformedValue 的空格替换为空格
@implementation DBAttributedStringTransformer
- (id)init
{
self = [super init];
if (self) {
appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
}
return self;
}
+ (Class)transformedValueClass
{
return [NSAttributedString class];
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
- (id)transformedValue:(id)value
{
return [appDelegate replaceSpacesWithBlanks:value];
}
- (id)reverseTransformedValue:(id)value
{
return [appDelegate replaceBlanksWithSpaces:value];
}
d) NSTextViewDelegate 在文本更改时用空白替换空格
@implementation DBTextViewDelegate
-(void)awakeFromNib {
appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
}
- (void)textViewDidChangeSelection:(NSNotification *)aNotification{
// Need to keep track of where the cursor should be reinserted
textLength = myTextView.string.length;
insertionPoint = [[[myTextView selectedRanges] objectAtIndex:0] rangeValue].location;
}
//replaces spaces with blank image and puts cursor back in correct position
- (void)textDidChange:(NSNotification *)aNotification{
NSInteger newTextLength = myTextView.string.length;
NSInteger newInsertionPoint = insertionPoint + newTextLength - textLength;
NSString * stringValue = [[NSUserDefaults standardUserDefaults] stringForKey:@"textViewString"];
NSAttributedString * attrStringWithBlanks = [[ NSAttributedString alloc] initWithAttributedString:[appDelegate replaceSpacesWithBlanks:stringValue ]];
NSMutableAttributedString *mutableString = [[NSMutableAttributedString alloc] initWithAttributedString:attrStringWithBlanks];
[myTextView.textStorage setAttributedString: mutableString];
//Put the cursor back where it was
[myTextView setSelectedRange:NSMakeRange(newInsertionPoint, 0)];
}
e) 子类 NSTextView 在写入粘贴板之前用复制或剪切文本上的空格替换空白
@implementation DBTextView
-(void)awakeFromNib {
appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
}
-(void) selectedTextToClipBoard{
NSRange selectedRange = [self selectedRange];
NSAttributedString * selectedText = [[self textStorage] attributedSubstringFromRange: selectedRange];
NSString * textWithoutBlanks = [appDelegate replaceBlanksWithSpaces:selectedText];
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
[pasteboard clearContents];
NSArray *copiedObject = [NSArray arrayWithObject:textWithoutBlanks];
[pasteboard writeObjects:copiedObject];
}
-(void) copy:(id)sender{
[self selectedTextToClipBoard];
}
-(void) cut:(id)sender{
[self selectedTextToClipBoard];
// Delete selected text so it acts like a cut
NSRange selectedRange = [self selectedRange];
[[self textStorage] deleteCharactersInRange:selectedRange];
}
f) 分配给步进器以更改尺寸的操作
- (IBAction)changeWordSpacing:(id)sender {
CGFloat imageWidth = [[NSUserDefaults standardUserDefaults] integerForKey:@"wordSpacing"];
NSImage * pic = [[NSImage alloc] initWithSize:NSMakeSize(imageWidth, 1.0f)];
NSTextAttachmentCell *attachmentCell = [[NSTextAttachmentCell alloc] initImageCell:pic];
NSMutableAttributedString * mutAttrString = [[NSMutableAttributedString alloc] initWithAttributedString:[textView textStorage]];
for (int index = 0; index < mutAttrString.length; index += 1) {
NSRange theRange;
NSDictionary * theAttributes = [mutAttrString attributesAtIndex:index effectiveRange:&theRange];
NSTextAttachment *theAttachment = [theAttributes objectForKey:NSAttachmentAttributeName];
if(theAttachment != NULL) {
[theAttachment setAttachmentCell: attachmentCell ];
}
}
[[textView textStorage] setAttributedString:mutAttrString];
}
另外,NSTextView 应设置为“连续更新值”