2014-08-31 92 views
3

我想在NSTextView中替換部分文本後實現撤消操作。我用下面的代碼如何使用NSTextview實現撤消

- (void)omeAction 
{ 
    NSString *fullString = [self.textView string]; 
    NSRange selectedRange = [self.textView selectedRange]; 
    NSString *selectedString = [fullString substringWithRange:selectedRange]; 

    NSString *stringToReplace = ...; 
    [[self.textView textStorage] beginEditing]; 
    [[self.textView textStorage] replaceCharactersInRange:selectedRange withString:stringToReplace]; 
    [[self.textView textStorage] endEditing]; 
} 

替換文本的一部分在執行撤消我真的無法撤消的文本替換

回答

6

Cocoa Text Architecture Guide: Text Editing – Text Change Notifications and Delegate Messages

在實際的文本進行修改,你必須確保文本系統的不同部分正確執行和記錄更改。您可以通過使用shouldChangeTextInRange:replacementString:和didChangeText消息將每批潛在更改括起來來實現此目的。這些方法確保發送適當的委託消息併發布通知。 ...

根據我的經驗,這包括生成相關的撤銷操作。

所以,你會怎麼做:

if ([self.textView shouldChangeTextInRange:selectedRange replacementString:stringToReplace]) 
{ 
    [[self.textView textStorage] beginEditing]; 
    [[self.textView textStorage] replaceCharactersInRange:selectedRange withString:stringToReplace]; 
    [[self.textView textStorage] endEditing]; 
    [self.textView didChangeText]; 
} 
+0

道歉,沒看過完整的問題。我認爲這是一般的撤銷(模糊的問題標題)。在我的情況下,撤消根本不起作用,結果是nstextview根本沒有註冊某些關鍵事件。無視 – 2017-03-08 14:56:45

+0

謝謝,shouldChangeTextInRange幫助啓動撤消正常工作 – 2017-10-18 18:13:11

0

首先,我試圖解決的撤消和shouldChangeTextInRange:replacementString:沒有的伎倆。不過,我發現insertText:replacementRange:具有相同的效果。

[self insertText:attributedString replacementRange:range]; 

或者:

if ([textView shouldChangeTextInRange:range replacementString:string]) { //string 
    [textStorage beginEditing]; 
    [textStorage replaceCharactersInRange:range withAttributedString:attributedString]; 
    [textStorage endEditing]; 
    [textView didChangeText]; 
}