在NSTextView中更改空格字符的宽度 [英] Changing the width of the space character in NSTextView

查看:76
本文介绍了在NSTextView中更改空格字符的宽度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个阅读器应用程序,以帮助有阅读困难的女孩.一些研究表明,仅更改文本,背景和阴影的颜色确实可以帮助孩子,所以我尝试让她这样做.它只是一个带有按钮的大NSTextView,因此她可以更改字体大小,颜色,背景颜色,阴影属性,字母间距,行间距和单词间距.我知道您可以仅使用Word来完成大多数操作,但我正在努力让它对她来说尽可能直观/有趣.

I’m trying to make a reader application to help a girl with reading difficulties. Some research shows that just changing the colors of the text, background and shadow can really help kids out so I’m trying to allow her to do that. It’s just a big NSTextView with buttons so she can change the font size, color, background color, shadow properties, letter spacing, line spacing and word spacing. I know you can do most of this just using Word but I’m trying to make it as intuitive/fun as possible for her.

我可以动手的地方是改变单词之间的间距大小.目前,我只是在搜索一串等于我期望存在的空格数的空格,然后用或多或少的空格替换它,如下所示:

The place where I could use a hand is in changing the size of the spacing between words. Currently I’m just searching for a string of spaces equal to the number of spaces I expect to be there and then replacing with more or less spaces it as follows:

- (IBAction)increaseSpacing:(id)sender{ 

  NSInteger spacing = [[NSUserDefaults standardUserDefaults] integerForKey:@"wordSpacing"];
  NSMutableString * oldString = [ NSMutableString stringWithCapacity:0];
  NSMutableString * newString =[ NSMutableString stringWithCapacity:0];

  for (int i = 0; i < spacing; i+=1) {
    [oldString appendString:@" "];
  }

  [newString setString:oldString];
  [newString appendString:@" "];

  [[[textView textStorage] mutableString] replaceOccurrencesOfString:oldString
                           withString:newString options:0
                                range:NSMakeRange(0, [[textView textStorage] length])];

  spacing += 1;

  [[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInteger: spacing] forKey:@"wordSpacing"];

}

- (IBAction)reduceSpacing:(id)sender{

  NSInteger spacing = [[NSUserDefaults standardUserDefaults] integerForKey:@"wordSpacing"];

  if (spacing > 1) {

    NSMutableString * oldString = [ NSMutableString stringWithCapacity:0];
    NSMutableString * newString =[ NSMutableString stringWithCapacity:0];

    for (int i = 0; i < spacing-1; i+=1) {

      [newString appendString:@" "];

    }

    [oldString setString:newString];
    [oldString appendString:@" "];

    [[[textView textStorage] mutableString] replaceOccurrencesOfString:oldString
                                                        withString:newString options:0
                                                             range:NSMakeRange(0, [[textView textStorage] length])];
    spacing -= 1;
    [[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInteger: spacing] forKey:@"wordSpacing"];

  }

}

这种方法让我感到草率,尤其是在使用箭头键移动光标时.我可以只键入空格字符时更改其字体大小,但这也会改变行高.有什么办法可以改变空格字符的宽度吗?预先感谢您的帮助.

This approach feels sloppy to me, especially when moving the cursor around with arrow keys. I could just change the font size of a space character when it’s typed, but that would also change the line height. Is there a way that I can just change the width of the space character? Thanks in advance for your help.

推荐答案

我最终的解决方案是换掉宽度已调整的空白图像(空白)的空间.

My eventual solution was to swap out spaces for blank images (blanks) that have the adjusted width.

基本组成部分:
a)用空格替换空格的方法
b)用空格替换空白的方法
c)用于NSTextView的NSValueTransformer(a)用于transformedValue,(b)用于reverseTransformedValue
d)NSTextViewDelegate在文本更改时执行(a)
e)子类NSTextView在复制或剪切的文本上执行(b),然后发送到粘贴板
f)分配给步进器以进行尺寸更改的动作

Basic components:
a) Method to replace spaces with blanks
b) Method to replace blanks with spaces
c) NSValueTransformer for the NSTextView to do (a) for transformedValue and (b) for reverseTransformedValue
d) NSTextViewDelegate to do (a) when the text changes
e) Subclass NSTextView to do (b) on copied or cut text before sending to pasteboard
f) Action assigned to the stepper to make the size changes

每个部分的代码如下:

a)AppDelegate方法,用空格替换空格

a) AppDelegate method to replace spaces with blanks

- (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方法,用空格替换空白

b) AppDelegate method to replace blanks with spaces

- (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)用于NSTextView的NSValueTransformer,以空格代替空白的transformedValue,并以空格代替reverseTransformedValue

c) NSValueTransformer for the NSTextView to replace spaces with blanks for transformedValue and replace blanks with spaces for 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在文本更改时用空格替换空格

d) NSTextViewDelegate to replace spaces with blanks when the text changes

@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,可在写入粘贴板之前在复制或剪切的文本上用空格替换空白

e) Subclass NSTextView to replace blanks with spaces on copied or cut text before writing to pasteboard

@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)分配给步进器以进行尺寸更改的动作

f) Action assigned to the stepper to make the size changes

- (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应该设置为连续更新值"

Also, NSTextView should be set to "Continuously Updates Value"

这篇关于在NSTextView中更改空格字符的宽度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆