NSUndoManager только отменить, а не повторить

#ios #objective-c

#iOS #objective-c

Вопрос:

Я пишу простую отмену и повторяю изменение цвета фона на основе примера кода NSUndoManager. Все хорошо работает с действием отмены. Но с помощью Redo он не переходит к методу регистрации для NSUndoManager, зарегистрированному ранее. Следуйте коду:

 #import "ViewController.h"
enum color {kWhite = 0, kRed, kOrange, kYellow, kGreen, kCyan, kBlue, kMagenta};
@interface ViewController (){
  enum color kColor;
  NSArray * colorArr;
  NSUndoManager * undoManager;
}
- (IBAction)changeColor:(id)sender;
- (IBAction)undo:(id)sender;
- (IBAction)redo:(id)sender;


@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.]
  kColor = kWhite;
  colorArr = [NSArray arrayWithObjects:[UIColor whiteColor], [UIColor redColor], [UIColor orangeColor], [UIColor yellowColor], [UIColor greenColor], [UIColor cyanColor], [UIColor blueColor], [UIColor magentaColor], nil];
  undoManager = [[NSUndoManager alloc] init];
  undoManager.levelsOfUndo = 7;

  NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];
  [nc addObserver:self selector:@selector(undoManagerDidUndo:) name:NSUndoManagerDidUndoChangeNotification object:self.undoManager];
  [nc addObserver:self selector:@selector(undoManagerDidRedo:) name:NSUndoManagerDidRedoChangeNotification object:self.undoManager];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)changeColor:(id)sender {
  [[undoManager prepareWithInvocationTarget:self]
   setcolor:kColor];

    kColor   ;
    if(kColor > kMagenta) kColor = kWhite;

  [self.view setBackgroundColor:colorArr[kColor]];
}
-(void) setcolor:(enum color) color{
  kColor = color;
  [self.view setBackgroundColor:colorArr[kColor]];
  NSLog(@"zzzz %d", color);
};

- (IBAction)undo:(id)sender {
  [undoManager undo];
}

- (IBAction)redo:(id)sender {
  [undoManager redo];
}

#pragma mark - Undo support

// -------------------------------------------------------------------------------
//  undoManagerDidUndo:
//  Handler for the NSUndoManagerDidUndoChangeNotification.  Redisplays the table
//  view to reflect the changed value.
//  See also: -setEditing:animated:
// -------------------------------------------------------------------------------
- (void)undoManagerDidUndo:(NSNotification *)notification
{
    //[self.view setBackgroundColor:colorArr[kColor]];
}

// -------------------------------------------------------------------------------
//  undoManagerDidRedo:
//  Handler for the NSUndoManagerDidRedoChangeNotification.  Redisplays the table
//  view to reflect the changed value.
//  See also: -setEditing:animated:
// -------------------------------------------------------------------------------
- (void)undoManagerDidRedo:(NSNotification *)notification
{
    //[self.view setBackgroundColor:colorArr[kColor]];
}
@end
  

Ответ №1:

 //
//  ViewController.m
//  UndoManager
//
//  Created by Eugene Buleyko on 01.08.14.
//  Copyright (c) 2014 Eugene Buleyko. All rights reserved.
//

#import "ViewController.h"

enum color {kWhite = 0, kRed, kOrange, kYellow, kGreen, kCyan, kBlue, kMagenta};

@interface ViewController () {
    enum color kColor;
    NSArray * colorArr;
    NSUndoManager * undoManager;
}

- (IBAction)changeColor:(id)sender;
- (IBAction)undo:(id)sender;
- (IBAction)redo:(id)sender;

@end

@implementation ViewController

@synthesize buttonRedo, buttonUndo;

- (void)viewDidLoad
{
    [super viewDidLoad];

    kColor = kWhite;
    colorArr = [NSArray arrayWithObjects:[UIColor whiteColor], [UIColor redColor], [UIColor orangeColor], [UIColor yellowColor], [UIColor greenColor], [UIColor cyanColor], [UIColor blueColor], [UIColor magentaColor], nil];
    undoManager = [[NSUndoManager alloc] init];
    undoManager.levelsOfUndo = 9;

    NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self selector:@selector(undoManagerDidUndo:) name:NSUndoManagerDidUndoChangeNotification object:self.undoManager];
    [nc addObserver:self selector:@selector(undoManagerDidRedo:) name:NSUndoManagerDidRedoChangeNotification object:self.undoManager];

    [self setcolor:kColor];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (IBAction)changeColor:(id)sender {

    kColor   ;

    if (kColor > kMagenta) {
        kColor = kWhite;
    }
    [self setcolor:kColor];

    [self.view setBackgroundColor:colorArr[kColor]];

}
-(void) setcolor:(enum color) color{

//    if ([self.view backgroundColor] == colorArr[color]) {
//       NSLog(@"==");
//        
//    } else {
//        NSLog(@"!=");
//    }

    kColor = color;

    [[undoManager prepareWithInvocationTarget:self] setcolor:kColor];
    //[undoManager setActionname:@"Add"];
};


- (IBAction)undo:(id)sender {
    [undoManager undo];
}

- (IBAction)redo:(id)sender {
    [undoManager redo];
}

#pragma mark - Undo support

- (void)undoManagerDidUndo:(NSNotification *)notification
{
    [self.view setBackgroundColor:colorArr[kColor]];

    if (![undoManager canUndo]) self.buttonUndo.enabled = NO;
    if ([undoManager canRedo]) self.buttonRedo.enabled = YES;

}

- (void)undoManagerDidRedo:(NSNotification *)notification
{
    [self.view setBackgroundColor:colorArr[kColor]];

    if (![undoManager canRedo]) self.buttonRedo.enabled = NO;
    if ([undoManager canUndo]) self.buttonUndo.enabled = YES;
}


@end
  

Комментарии:

1. может быть, несколько слов о том, что вы добавили / изменили, поможет.