如何通过编程更改 NSTextView 的文本值来实现撤消/重做?

2024-01-10

我创建了一个带有 NSTextView 和按钮的简单演示应用程序,为 textView 提供了 NSTextViewDelegate 并添加了一个操作:

- (IBAction)actionButtonClicked:(id)sender {
    NSString *oldText = [[[self.textView textStorage] string] copy];
    NSString *newText = @"And... ACTION!";

    [[self.textView undoManager] registerUndoWithTarget:self.textView
                                               selector:@selector(setString:)
                                                 object:oldText];
    [[self.textView undoManager] setActionName:@"ACTION"];

    [self.textView setString:newText];
}

如果我手动更改文本,撤消/重做工作不会出现问题。但是,如果我使用操作方法更改文本,撤消将按预期工作,但重做不再起作用(什么也没有发生)并且撤消管理器似乎被打乱......

好的 - 为了避免 NSTextView 出现问题,我创建了一个模型类,将 NSTextView 绑定到它并将撤消/重做移动到模型,但这显示了与以前相同的行为 - 我做错了什么 - 这应该很容易,不应该吗?

#import "GFTextStore.h"

@implementation GFTextStore

@synthesize textVal = textVal_;

-(void)changeText{
    if (!undoMan_) {
        undoMan_ = [[[NSApplication sharedApplication] mainWindow] undoManager];   
    }

    NSAttributedString *oldText = [self.textVal copy];
    NSString *tempStr = [[oldText string] stringByAppendingFormat:@"\n%@",[[NSCalendarDate date]description]];
    NSAttributedString *newText = [[NSAttributedString alloc] initWithString:tempStr];

    [self setTextVal:newText];


    [undoMan_ registerUndoWithTarget:self
                            selector:@selector(setTextVal:)
                              object:oldText];

    [undoMan_ setActionName:@"ACTION"];
}
@end

此处无需添加 NSUndoManager,只需让 NSTextView 完成该工作即可。

您只需要确保您正在致电仅更高级别的方法NSTextView 开头为insert…并且不直接设置textView或textStorage的文本/字符串:

    [self.textView insertText:newString];

如果您绝对需要使用 setString 或其他较低级别的方法,那么您只需添加处理 textDidChange 委托所需的方法:-shouldChangeTextInRange:替换字符串 and -did更改文本(这是通过 insert... 方法完成的):

if( [self.textView shouldChangeTextInRange:editedRange replacementString:editedString]) {
    // do some fancy stuff here…
    [self.textView.textStorage replaceCharactersInRange:editedRange
                          withAttributedString:myFancyNewString];
    // … and finish the editing with
    [self.textView didChangeText];
}

这会自动让 NSTextView 的 undoManager 启动。我认为 undoManager 正在 shouldChangeTextInRange: 中准备撤消分组,并在 didChangeText: 中调用撤消。

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

如何通过编程更改 NSTextView 的文本值来实现撤消/重做? 的相关文章

随机推荐

  • Angular Typescript getter 和 setter 返回未定义

    我有一个类 我需要该类中的属性来返回对象中的一些字段 我在 Net 中这样做过几次 但在 Angular 中 我正在与返回的 未定义 作斗争 我可以确认属性 transLanguageId transLangDesc 翻译 已填充到 IBa
  • 如何解决 VS2013 错误 SQL71501:过程 X 对程序集 Y 存在未解析的引用?

    作为从 Visual Studio 2010 升级到 2013 的努力的一部分 我正在研究几个需要的 SQL Server CLR 存储过程EXTERNAL访问 并为此目的被隔离在一个单独的程序集中 我几乎可以毫无困难地构建所有东西 但这给
  • 如何更改 Capistrano 使用的临时目录?

    如何更改 Capistrano 使用的临时目录 示例 代替 tmp 我想用 home user tmp 我目前的VPS有 tmp安装为noexec 这在尝试运行时给了我权限被拒绝的错误cap production deploy 在 卡皮斯特
  • 用于撰写 Facebook 电子邮件/消息的 URL(通过 URL 参数撰写电子邮件)

    Facebook 过去使用以下 URL 格式来撰写消息 http www facebook com compose id XXXXXX message 然而 上面的 URL 不再起作用 它只是将用户转发到 Facebook 主页 有人可以通
  • 有没有办法以编程方式确定图像链接是错误的?

    在我正在处理的网站中 显示的图像并不总是 显示 因为链接可能是坏的或过时的 或其他什么 你可以在这里看到它 为什么我的动态 HTML 看起来是随机放置的 https stackoverflow com questions 17689644
  • 在 Facebook 上分享的人员列表

    我已经搜索文档有一段时间了 但似乎找不到实现此目的的方法 这些信息是公开的 在 Facebook 页面上 链接显示 查看所有 股 但我似乎找不到通过 FQL 或图形 API 访问此信息的方法 我知道我可以获得给定帖子的点赞列表 https
  • Haskell 中“undefined”的类型签名意味着什么?

    我是 Haskell 的初学者 我对undefined函数的类型签名 我期望有更简单的东西 但我在 Hackage 上发现了这个 undefined forall r RuntimeRep forall a TYPE r HasCallSt
  • 自引用表 SQL 查询

    我有一个有四列的表格id name designation manager id 表架构 CREATE TABLE Employee Information id INTEGER PRIMARY KEY AUTOINCREMENT NOT
  • excel中的数组改变字符串的格式

    我想要分离图像中的数据 图像中的代码一旦到达分号和缩进就不会分开 我想将这些单词分离到一张新纸上 以便我将在数组中搜索某些单词 谢谢您的帮助 下面的代码不仅会分割数据 还会复制格式 这似乎是您想要的 假设数据位于 A 列 Option Ex
  • Windows Phone 8.1 API

    有 Windows Phone 8 1 API 可供参考吗 这是因为我想开发Windows Phone 8 1应用程序 但我不知道在哪里引用API 因为Windows Phone 8 1和8有很大的不同 所以我无法引用Windows Pho
  • 点击即可从 SwiftUI 小部件执行深层链接

    我有一个带有两个文本的简单小部件 中等大小 我想要的是能够执行深层链接以引导用户到我的应用程序的特定部分 但我似乎找不到一种方法这样做 我写的视图 很简单 HStack Text FIRST ITEM Spacer Text SECOND
  • liquibase <插入> :插入当前日期

    我正在尝试使用 liquibase 插入标签插入数据 当我向 value tag 输入数字时 它工作正常 但我正在寻找一个简单的函数来处理默认日期 数据库的当前日期时间 即使我没有将它作为表定义的一部分 Eg
  • 如何将 null 传递给需要 long 或 int 的方法?

    可能是个愚蠢的问题 但我怎样才能通过null到需要的方法long or int Example TestClass public void iTakeLong long id public void iTakeInt int id 现在我如
  • MicroProfile 指标在 Wildfly 25 上不显示自定义指标

    我正在尝试 Javax JaxRs 并且使用的是 WildFly 25 服务器 我对此不太熟悉 在搜索类似于 Spring 的 Actuator 的东西时 我偶然发现了服务器默认公开的指标和运行状况端点 以及它向应用程序端点添加自定义计数器
  • Ember:点击时动态添加输入字段并读取新数据

    我有一个页面 向用户展示几个问题并提供答案的输入字段 我还有一个按钮添加问题 单击此按钮后 他可以在新的输入字段中输入问题 然后单击 保存 所以我需要的是 当他保存时 新输入的问题也应该显示在已经显示的问题附近 所以我对模型有疑问 impo
  • 使用 Ecto 的时间戳向现有表添加时间戳

    这已被问到这里如何使用 Ecto 的时间戳向现有表添加时间戳 https stackoverflow com questions 35744390 how to add timestamps to an existing table wit
  • 未经检查的“java.util.ArrayList”分配

    我收到警告 未经检查的将 java util ArrayList 分配给 java util ArrayList for private ArrayList
  • 6.0.1 和表更改“UILabel?没有名为“text”的成员

    我正在研究 Swift 表演示 所有这些演示在 6 0 1 下似乎都有相同的错误消息 不知道如何解决这个问题 尝试这个 cell textLabel text self tableData indexPath row 并在此处阅读有关可选选
  • Firefox 不会显示 2 行文本区域的滚动条

    如果我设置高度以便实际只显示两行 则 Firefox 将不会在 2 行文本区域中显示滚动条 我必须让它足够大才能显示下面一行的一部分 有人解决过这个问题吗 我创建了一个jsfiddle http jsfiddle net briank AT
  • 如何通过编程更改 NSTextView 的文本值来实现撤消/重做?

    我创建了一个带有 NSTextView 和按钮的简单演示应用程序 为 textView 提供了 NSTextViewDelegate 并添加了一个操作 IBAction actionButtonClicked id sender NSStr