撤消 UITextView 中的输入

发布于 2024-08-16 23:52:20 字数 744 浏览 5 评论 0原文

我正在使用 iPhone SDK 3.0。

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

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

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

有人有主意吗?

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

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

I'm using iPhone SDK 3.0.

Say, I enabled 'shake to undo' by setting application.applicationSupportsShakeToEdit to YES in my app delegate. I created an UITextView in RootViewController and had it become first responder upon app launch.

I use - (BOOL)textView:(UITextView *)aTextView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text to make changes to the text view according to what the user types. The problem is that it messed up the default undoing action. Shaking the device no longer display 'Undo Typing'.

I tried to create an undo manager myself but have yet to success. Nothing shows up when I shake my device, even though I had the undo manager registered some actionprepareWithInvocationTarget.

Anyone has an idea?

EDIT: I have checked WriteRoom for iPhone's behavior and also TextExpander Touch SDK example code, both of which display the Undo option upon shaking until an auto-completion is made. That is, when a change is commited to the textView via setText:, I guess. So, changing the textView's content indeed has some effects on the undo mechanism.

EDIT 2: The question is that: How could I incorporate the undo feature in this case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

GRAY°灰色天空 2024-08-23 23:52:20

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

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

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 -

How to incorporate your own undo? Here is the simplest approach possible.

NOTE: this does not respond to shake gesture in simulator.

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 -
情绪 2024-08-23 23:52:20

applicationSupportsShakeToEditYES 所以实际上不需要打开它。

我不确定您的问题/问题没有代码,但有可能通过在 UITextViewDelegate textView:shouldChangeTextInRange 你可能会很短 -循环 UndoManager 魔法的发生。您可能需要检查该委托方法内的逻辑以确保不会发生这种情况,或者可能使用不同的委托消息,例如 textViewDidChange:

The default value for applicationSupportsShakeToEdit is YES so there really shouldn't be any need to turn that on.

I'm not sure exactly what your question/problem is without code, but it's possible that by returning NO on UITextViewDelegate textView:shouldChangeTextInRange you could be short-circuiting the UndoManager magic happening. You might need to review that logic inside that delegate method to make sure that is not happening, or perhaps use a different delegate message like textViewDidChange: instead.

爱,才寂寞 2024-08-23 23:52:20

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

I found the implementation, at least in 3.1 to be buggy and opted to not use undo at all in my app. The bug involved the undo mechanism adding extra undos under certain circumstances, so making the message displayed to the user not make any sense.

鸠书 2024-08-23 23:52:20

您是否看过这里的源代码: http://github.com/dcgrigsby/TallyTrucks/tree /大师
它有 NSUndoManager 的基本(工作)实现。也许它会有所帮助。

Have you looked at the source code here: http://github.com/dcgrigsby/TallyTrucks/tree/master
It has a basic (working) implementation of the NSUndoManager. Possibly it could help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文