更改 NSTextView 中空格字符的宽度

2024-05-02

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

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

- (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"];

  }

}

这种方法对我来说感觉很草率,尤其是在用箭头键移动光标时。我可以在键入空格字符时更改其字体大小,但这也会更改行高。有没有办法可以改变空格字符的宽度?在此先感谢您的帮助。


我最终的解决方案是将空间替换为具有调整宽度的空白图像(空白)。

基本组成:
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 应设置为“连续更新值”

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更改 NSTextView 中空格字符的宽度 的相关文章

  • Objective C (iphone) 关于发布的问题

    如果我创建一个视图 并将其添加为子视图并将其添加到数组中 是否必须释放它两次 UIView cat UIView alloc initWithFrame someFrame self view addSubview cat self ani
  • 如何从 Mac OS X 中完全删除 Eclipse(包括设置和插件)?

    我的 Eclipse 与 GAE 损坏并且工作异常 所以我从Application文件夹中删除了Eclipse 但是留下了垃圾 我重新下载了全新的 eclipse 但它以旧设置运行 并且损坏的 GAE 结构仍然存在 如何从 Mac 上完全删
  • 如何在应用程序项目中使用 Cocoa Touch 框架

    我熟悉构建单个 iOS 应用程序 但我坚持使用 Cocoa Touch 框架向多个应用程序共享通用代码 问题 框架的头文件不可见 无法链接到消费应用程序项目 我做了什么 1 我创建了一个名为 libTestFramework 的项目 Coc
  • 使用自动布局、IB 和字体大小时表头视图高度错误

    我正在尝试为我的 uiTableView 创建一个标题视图 不是节标题 我已经有了 我已经在界面生成器中设置了一个 XIB 所有的连接都已连接好并且运行良好 除了桌子没有给它足够的空间 我的问题是表格顶部与表格标题有一点重叠 我的 XIB
  • Objective C 中类别是如何实现的?

    作为一名程序员 我知道如何使用类别 但我很好奇它们是如何实现的 编译器是否将它们编译为对类替换方法 http developer apple com library mac documentation Cocoa Reference Obj
  • 如何为 Nslocal 通知设置自定义重复间隔......?

    我是 iphone 开发新手 我正在尝试在我的项目中使用 NslocalNotification 我需要每 2 小时或每两天或每两个月等给出提醒 目前我正在使用 NslocalNotification 重复间隔 但它仅适用于使用 Ncale
  • 在 Mac OSX 上从 Python 3.6 运行 wine 命令

    我正在尝试用 Python 编写一个打开的脚本wine然后发送代码到wine终端打开一个 exe程序 这 exe程序也是命令驱动的 我可以打开wine 但我无法进一步 import shlex subprocess line usr bin
  • 在 Mac OS X 上安装 libxml2 时出现问题

    我正在尝试在我的 Mac 操作系统 10 6 4 上安装 libxml2 我实际上正在尝试在 Python 中运行 Scrapy 脚本 这需要我安装 Twisted Zope 现在还需要安装 libxml2 我已经下载了最新版本 2 7 7
  • 带有文本字段的 iPhone AlertView

    我有一个UIAlertView with a UITextField在里面 我想输入mail id并提交于UIAlertView s ok按钮 但是UITextField in the UIAlertView没有回复 请帮助我 thankz
  • 在 MacOS 终端上运行 ffmpeg [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我对 MacOS 相当陌生 我发现使用终端来获取信息并不容易ffmpeg和我在 Window 上一样正常运行 我有 ffmpeg 二进制文件ffmpe
  • 对象指针值作为字典的键

    我想使用对象的引用值作为字典的键 而不是对象值的副本 因此 我本质上想在字典中存储与另一个对象的特定实例关联的对象 并稍后检索该值 这可能吗 是不是完全违背了NSDictionary的理念 我可以看出我可能以错误的方式处理这个问题 因为字典
  • 开发者可以在 Windows 应用程序中使用 iCloud 吗?

    开发人员可以使用 Apple 的 iCloud API 在 Mac OS X 和 iOS 上的不同版本的应用程序之间同步应用程序数据 如果开发人员拥有 Windows 版本的应用程序 该版本是否也可以使用 iCloud 将应用程序数据与 M
  • 如何在 swiftUI (macOS) 中检测按键按下和释放

    除了标题之外没什么可说的 我希望能够在按下按键和释放按键时 在 macOS 上 在 swiftUI 视图中执行操作 在 swiftUI 中是否有任何好的方法可以做到这一点 如果没有 有什么解决方法吗 不幸的是 键盘事件处理是其中一个令人痛苦
  • 如何去掉 UIWebView 上的状态栏背景?

    从 iOS 11 开始 当UIWebView全屏时 状态栏上会出现与屏幕颜色相同的假背景UIWebView背景 有人知道如何摆脱它吗 甚至添加IUWebView到故事板并使其全屏将使状态栏背景出现 我一直在尝试编辑 UIWebView 的大
  • 更改导航项(栏)的背景颜色

    有没有一种简单的方法可以更改视图顶部导航项的背景颜色 我有一个基于导航的应用程序 我只希望一个视图获得另一种背景颜色 我主要使用 IB 创建视图 我找到了以下解决方案 未测试 float r 10 float g 55 float b 13
  • .profile 无法从 Mac 终端运行

    我有一个 profile 文件 我正在终端中读取并使用别名 但在某些时候 别名由于没有明确的原因而停止工作 其他命令仍在工作 为了快速修复 我删除了 rm 并在用户目录中重新创建了 profile 文件 我可以看到 至少在该目录中没有 ba
  • 如何从 AFNetworking 和 AFJSONRequestOperation 获取可变字典?

    我将 JSONKit 与 AFNetworking 的 AFHTTPClient 带有 AFJSONRequestOperation 一起使用 我似乎无法弄清楚如何触发使用 JSONKit 的 mutableObjectFrom 方法 而不
  • ios 在后台处理推送通知

    我想保存应用程序处于后台状态时到达的推送通知 我知道关于 void application UIApplication application didReceiveRemoteNotification NSDictionary userIn
  • Java Swing For mac 中的 DJ Native Swing 浏览器

    我有一个用 Swing 制作的 Java 应用程序 并且使用了一个 DJ Native Swing 浏览器 当我尝试在 OS X 上使用它时 它抛出了一个NoClassDefFoundError尽管我添加了 swt jar 但始终如此 有人
  • OSX 上的 locale.getlocale() 问题

    我需要获取系统区域设置来执行许多操作 最终我想使用 gettext 翻译我的应用程序 我打算在 Linux 和 OSX 上分发它 但我在 OSX Snow Leopard 上遇到了问题 python Python 2 5 2 r252 60

随机推荐

  • C#中同步接口和实现注释的方法

    是否有自动方法在接口及其实现之间同步注释 我目前正在记录它们 并且不想手动使它们保持同步 UPDATE 考虑这段代码 interface IFoo
  • Spring Web 连接到嵌入 Jboss 服务器 7.1.1 的 HornetQ JMS

    我正在尝试设置 spring web 以通过以下方式连接到远程 Jboss 7 1 1 HornetQ JMSthis http java dzone com articles connecting spring地点 但我收到以下错误 是否
  • 检索属于特定命名空间的所有实体时返回的内部类型

    我正在尝试检索属于特定名称空间的所有实体 查询非常简单 query datastore Query namespace
  • 如何阻止连续打印多个买入/卖出信号?

    我正在尝试用我的脚本实现一些目标 如果前一个信号是 卖出 我只想打印 买入 信号 反之亦然 我只想在小于之前的 卖出 信号时打印 买入 信号 反之亦然 我一整天都在努力寻找这个问题的解决方案 我不明白如何使用 valuewhen 或 bar
  • 如何通过管道将输入和输出传送到交互式 shell?

    我正在尝试构建一个应用程序 使用户能够与命令行交互式 shell 例如 IRB 或 Python 进行交互 这意味着我需要将用户输入通过管道传输到 shell 并将 shell 的输出返回给用户 我希望这会像管道 STDIN STDOUT
  • Android 数据库(SQLite)从空表返回非空游标

    我使用 SQLite 数据库浏览器验证该表不包含任何行 我单步执行查询生成器代码来获取生成的查询 并在 SQLite 数据库浏览器中运行该查询 查询返回零行 但是 Android 的 SQLiteQueryBuilder query 方法返
  • 如何了解来自不同...“命名空间”的变量?

    如何从外部 javascript 文件中访问在另一个地方声明的某个变量 假设在一个 html 文件中我有以下内容 在 otherfile html 的部分中 我有 alert a 我如何确保收到一条提示消息 某事 我认为Google Ads
  • 使用 webpacker 部署到 heroku 后,资产不存在于资产管道中

    我正在使用 Rails 5 2 3 我可以在本地下载 pdf 但Heroku它通过错误 500 错误是 ActionView Template Error 资源 pdf css 不存在于资源管道中 这是我的 Heroku 日志 2019 0
  • 如何在android上的manageQuery中添加限制子句

    Android 的 API 通过 SQLite 提供了一种干净的机制来查询联系人列表 但是 我不确定如何限制结果 Cursor cur Activity mCtx managedQuery People CONTENT URI column
  • 如何清除gwt中的缓存?

    我怎样才能清除缓存gwt 或者有什么方法可以阻止浏览器保留缓存gwt 当您部署 GWT 应用程序时 避免代理和浏览器缓存 GWT 生成的 nocache js 文件非常重要 一种解决方案是实现一个 Servlet 过滤器 添加控制缓存行为的
  • 如何在react-native应用程序中禁用屏幕截图?

    我已经使用react native制作了一个移动应用程序 目前只有android 它不是博览会应用程序 我想禁止用户在应用程序打开时截取屏幕截图 我知道不可能完全禁用此功能 但我想让至少更难截取屏幕截图 我找到了一些例子 但我不知道如何实现
  • 一元运算符 ++ 不能应用于 Int 类型的操作数

    为什么下面的 swift 代码会给我带来错误 一元运算符 不能应用于 Int 类型的操作数 在 Xcode 6 3 2 上使用 swift 1 2 struct Set var player1Games Int var player2Gam
  • 如何将多个域路由到多个节点应用程序?

    我习惯了典型的 Lamp Web 托管环境 您只需单击 cpanel 中的几个按钮 您的域就会被分区并映射到 htdocs 中的文件夹 我经常使用 Node js 但做同样的事情似乎并不那么简单 如果我有多个节点应用程序 并且我想将doma
  • 在大型文本文件中查找重复记录

    我在一台 Linux 机器 Redhat 上 并且有一个 11GB 的文本文件 文本文件中的每一行包含单个记录的数据 并且该行的前 n 个字符包含该记录的唯一标识符 该文件包含略多于 2700 万条记录 我需要验证文件中不存在具有相同唯一标
  • 将列从日期转换为日期时间

    我有一个名为Lastmodified 数据类型为Date 但本来应该是DateTime 有没有办法转换列 当我使用 SQL Server Management Studio 的 设计 功能时 出现以下错误 不允许保存更改 您所做的更改需要以
  • C 中的 NULL 是否需要/定义为零?

    在我的 GCC 测试程序中 NULL 似乎为零 但维基百科说NULL只需要指向不可寻址的内存 有编译器做吗NULL非零 我很好奇是否if ptr NULL 是比更好的练习if ptr NULL is guaranteed to be zer
  • 如何禁用 AngularJS 中输入的修剪?

    我发现了一些奇怪的行为 默认情况下角度修剪模型值 快速谷歌搜索并不能帮助我解决这个问题 我发现了ng no trim指导性建议 ng trim等等 但没有任何作用 我在下面提供了一个代表这个问题的小片段 function Ctrl scop
  • 解压缩 GZIP http 响应(使用 jersey 客户端 api、java)

    有人可以告诉我在从某些 Http 调用获取响应时需要做什么才能解压缩 GZIP 内容吗 为了进行调用 我使用 Jersey Client API 请参阅下面的代码 String baseURI http api stackoverflow
  • 在 C++ 中是否有一种简单的方法可以将由空格字符分隔的一行输入拆分为整数?

    我是一名 C 初学者 我一直在开发一个项目 在该项目中 您必须输入一些用空格分隔的整数 并且程序必须输出所有可能的整数排列 我知道在 python 中 这可以使用 int item for item in input split 但我不知道
  • 更改 NSTextView 中空格字符的宽度

    我正在尝试制作一个阅读器应用程序来帮助有阅读困难的女孩 一些研究表明 仅仅改变文本 背景和阴影的颜色确实可以帮助孩子们摆脱困境 所以我试图让她这样做 它只是一个带有按钮的大 NSTextView 因此她可以更改字体大小 颜色 背景颜色 阴影