4

我正在使用 iPhone SDK 3.0。

比如说,我通过在我的应用程序委托中设置application.applicationSupportsShakeToEdit为启用“摇晃撤消” 。YES我在 RootViewController 中创建了一个 UITextView,并让它在应用启动时成为第一响应者。

我用来- (BOOL)textView:(UITextView *)aTextView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text根据用户键入的内容来更改文本视图。问题是它搞砸了默认的撤消操作。摇动设备不再显示“撤消键入”。

我尝试自己创建一个撤消管理器,但尚未成功。即使我让撤消管理器注册了一些操作,当我摇动我的设备时也没有任何显示prepareWithInvocationTarget

有人有想法吗?

编辑:我检查了 iPhone 的 WriteRoom 行为以及 TextExpander Touch SDK 示例代码,它们都在摇动时显示 Undo 选项,直到自动完成。也就是说,当通过 setText: 向 textView 提交更改时,我猜。所以,改变 textView 的内容确实对 undo 机制有一些影响。

编辑 2:问题是:在这种情况下,我如何合并撤消功能?

4

4 回答 4

4

如何合并您自己的撤消操作? 这是最简单的方法。

注意:这不会响应模拟器中的摇晃手势。

UndoTestViewController.h:

@interface UndoTestViewController : UIViewController <UITextViewDelegate, UIAccelerometerDelegate>{
    IBOutlet UITextView *textview;
    NSString *previousText;
    BOOL showingAlertView;
}
@property (nonatomic,retain) NSString *previousText;
@end

UndoTestViewController.m:

@implementation UndoTestViewController
@synthesize previousText;

- (void)viewDidLoad {
    [super viewDidLoad];

    //disable built-in undo
    [UIApplication sharedApplication].applicationSupportsShakeToEdit = NO;

    showingAlertView = NO;

    [UIAccelerometer sharedAccelerometer].delegate = self; 
    [UIAccelerometer sharedAccelerometer].updateInterval = kUpdateInterval;

    //set initial undo text
    self.previousText = textview.text;
}

#pragma mark UITextViewDelegate
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

    //save text before making change
    self.previousText = textView.text;

    //changing text in some way...
    textView.text = [NSString stringWithFormat:@"prepending text %@",textView.text];
    [textView resignFirstResponder];
    return YES;
}
#pragma mark -

#pragma mark UIAccelerometerDelegate
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { 

    if( showingAlertView ) return;

    if ( acceleration.x > kAccelerationThreshold || 
        acceleration.y > kAccelerationThreshold || 
        acceleration.z > kAccelerationThreshold ) {


        showingAlertView = YES;
        NSLog(@"x: %f y:%f z: %f", acceleration.x, acceleration.y, acceleration.z);


        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Undo Typing", nil];
        alert.delegate = self;
        [alert show];
        [alert release];
    }
}
#pragma mark -

#pragma mark UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if( buttonIndex == 1 ) {
        textview.text = self.previousText;
    }
    showingAlertView = NO;
}
#pragma mark -
于 2010-01-06T17:23:29.693 回答
1

applicationSupportsShakeToEdit的默认值是YES所以真的不需要打开它。

如果没有代码,我不确定您的问题/问题到底是什么,但有可能通过返回NOUITextViewDelegate textView:shouldChangeTextInRange您可能会短路 UndoManager 魔术的发生。您可能需要检查该委托方法内的逻辑以确保没有发生这种情况,或者可能使用不同的委托消息textViewDidChange:代替。

于 2010-01-05T15:25:03.223 回答
0

我发现至少在 3.1 中的实现是错误的,并选择在我的应用程序中根本不使用撤消。该错误涉及在某些情况下添加额外撤消的撤消机制,因此使向用户显示的消息没有任何意义。

于 2010-01-03T00:07:55.520 回答
0

你看过这里的源代码吗:http: //github.com/dcgrigsby/TallyTrucks/tree/master 它有一个NSUndoManager 的基本(工作)实现。可能会有所帮助。

于 2010-01-05T21:16:14.727 回答