NSTextView ReplaceCharactersInRange:withString: 对应 shouldChangeTextInRanges:replacementStrings:
我的一个项目中有一个相当复杂的 NSTextView 子类。我目前正在努力让查找/替换与内联查找栏(例如 Safari、Xcode)一起使用,并希望正确支持替换操作的撤消/重做。
我希望“全部替换”命令支持将撤消作为单个命令(即,如果在文本视图中要进行 8 个替换,它也应该立即撤消这 8 个替换)。
我想知道是否有与 shouldChangeTextInRanges:replaceStrings:
相对应的内容,我可以在检查后调用它来进行替换。我预计会有一个 replaceCharactersInRanges:withStrings:
或类似的东西,但似乎没有。
目前我能想到的唯一方法是首先检查对 shouldChangeTextInRanges:replaceStrings:
的调用,然后使用整个范围调用 replaceCharactersInRange:withString:
文本视图和新字符串(已进行替换)作为第二个参数。
这似乎没有必要,如果不需要的话,我真的不想替换整个字符串。有什么想法吗?
I have a fairly complicated NSTextView subclass in one of my projects. I'm currently working on getting find/replace to work with an inline find bar (e.g. Safari, Xcode) and want to properly support undo/redo for the replace operations.
I want the Replace All command to support undo as a single command (i.e. if there are 8 replacements to be made in the text view, it should also undo those 8 replacements at once).
I'm wondering if there is a counterpart to shouldChangeTextInRanges:replaceStrings:
that I can call after checking to do the replacement. I expected there would be a replaceCharactersInRanges:withStrings:
or something similar, but there doesn't seem to be.
The only way I can think to do this at the moment is to check with a call to shouldChangeTextInRanges:replaceStrings:
first, then call replaceCharactersInRange:withString:
with the entire range of the text view and the new string (with the replacements made) as the second argument.
This just seems unnecessary, I don't really want to replace the entire string if I don't have to. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
经过一番修补后,我想我已经弄清楚了。乔希,我按照你的建议开始了。我不确定您是否编辑了您的建议或只是删除了它,但它已经消失了,所以我无法在答案中引用它。
不管怎样,你必须在每次调用replaceCharactersInRange:withString:之后改变你要替换的范围,否则会因为范围不匹配而发生不好的事情。这就是我最终得到的结果:
这非常有效并且支持按预期撤消,撤消此操作会立即撤消所有替换。
不管怎样,感谢乔什,因为他的回答让我指明了正确的方向。
After some tinkering I think I've got this figured out. Josh, I used your suggestion to get started. I'm not sure if you edited your suggestion or just deleted it, but it's gone so I can't quote it in my answer.
Anyways, you have to shift the ranges you are going to replace after each invocation of
replaceCharactersInRange:withString:
or else bad things happen as the ranges don't match up. Here is what I ended up with:This works great and supports undo as expected, undoing this operation results in all the replacements being undone at once.
Anyways thanks to Josh, as his answer got me pointed in the right direction.
令我惊讶的是,撤消操作并未自动分组。但是,您可以手动进行撤消分组;您必须自己设置相反的操作。希望这将为您指明正确的方向:
I'm surprised the undo for that isn't grouped automatically. However, you can do manual undo grouping; you'll have to set up the inverse actions yourself. Hopefully this will point you in the right direction: