objective-c – NSTextView replaceCharactersInRange:withString:shouldChangeTextInRanges:replacementStrings:

前端之家收集整理的这篇文章主要介绍了objective-c – NSTextView replaceCharactersInRange:withString:shouldChangeTextInRanges:replacementStrings:前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的一个项目中有一个相当复杂的NSTextView子类.我目前正致力于使用内联查找栏(例如Safari,Xcode)进行查找/替换,并希望正确支持撤消/重做以进行替换操作.

我希望Replace All命令支持undo作为单个命令(即如果在文本视图中有8个替换,它也应该同时撤消这8个替换).

我想知道是否存在shouldChangeTextInRanges的对应部分:replaceStrings:我可以在检查后进行替换.我预计会有一个replaceCharactersInRanges:withStrings:或类似的东西,但似乎没有.

我现在能想到的唯一方法是检查对shouldChangeTextInRanges的调用:replaceStrings:首先,然后调用replaceCharactersInRange:withString:整个文本视图范围和新字符串(替换为)第二个论点.

这似乎没必要,如果我不需要,我真的不想替换整个字符串.有任何想法吗?

解决方法

经过一些修修补补,我想我已经搞清楚了.乔希,我用你的建议开始了.我不确定你是否编辑了你的建议或者只是删除了它,但它已经消失了所以我不能在我的答案中引用它.

无论如何,你必须在每次调用replaceCharactersInRange:withString之后移动你要替换的范围:否则会发生不好的事情,因为范围不匹配.这是我最终得到的:

// array of NSValue objects storing an NSRange
NSArray *replaceRanges = [self replaceRanges];
NSString *replaceString = [self replaceString];
// array of NSString objects you are going to use for the replace operation,just replaceString repeated [replaceRanges count] times
NSArray *replaceStrings = [self replaceStrings];
NSTextView *textView = [self textView];
// the amount we have to shift subequent replace ranges after each call to replaceCharactersInRange:withString:
NSInteger locationShift = 0;

// check to makes sure the replace can occur
if ([textView shouldChangeTextInRanges:replaceRanges replacementStrings:replaceStrings]) {
    // we want to treat all these replacements as a single replacement for undo purposes
    [[textView textStorage] beginEditing];

    for (NSValue *rangeValue in replaceRanges) {
        NSRange range = [rangeValue rangeValue];

        // replace the range shifted by locationShift with our replaceString
        [[textView textStorage] replaceCharactersInRange:NSMakeRange(range.location + locationShift,range.length) withString:replaceString];

        // update the shift amount,which is the difference between our replaced string length and the original match length
        locationShift += [replaceString length] - range.length;
    }
    // end the grouping operation
    [[textView textStorage] endEditing];
}

这非常有用并支持按预期方式撤消,撤消此操作会导致所有替换一次撤消.

无论如何,感谢Josh,因为他的回答让我指出了正确的方向.

猜你在找的cocoa相关文章