Pergunta

Eu tenho um aplicativo baseado em documentos Core Data que suporte undo / redo através do built-in NSUndoManager associado ao NSManagedObjectContext. Eu tenho algumas ações criadas que realizam inúmeras tarefas dentro Core Data, envolva todas estas tarefas em um grupo de desfazer via beginUndoGrouping / endUndoGrouping, e são processados ??pelo NSUndoManager.

Undo funciona bem. Posso executar várias ações sucessivas, e cada um, em seguida, desfazer cada um deles sucessivamente e estado do meu aplicativo é mantido corretamente. No entanto, o item de menu "Refazer" não está habilitado. Isto significa que o NSUndoManager está dizendo o menu que não há itens para refazer.

Eu estou querendo saber por que o NSUndoManager é aparentemente esquecendo-se itens, uma vez que são desfeitas, e não permitindo redos a ocorrer?

Uma coisa que eu devo mencionar é que eu estou a desativação de desfazer o registro depois de um documento é aberto / criado. Quando eu executar uma ação, eu chamo enableUndoRegistration, beginUndoGrouping, executar a ação, em seguida, chamar processPendingChanges, setActionName:, endUndoGrouping e, finalmente disableUndoRegistration. Isso garante que apenas ações específicas são reversível, e quaisquer outros dados muda faço fora delas passam despercebidas ao NSUndoManager. Esta pode ser uma parte do problema, mas se isso estou perguntando por que ele está afetando refazer?

Agradecemos antecipadamente.

Foi útil?

Solução 2

Eu fixo esse problema:

Manter registro de desfazer habilitado o tempo todo, exceto para os momentos em que eu explicitamente não quer desfazer recordes.

Eu aprendi que:

Se você habilitar o registro de desfazer apenas antes de realizar as mudanças que você deseja gravar, e desabilitar imediatamente após cometer essas mudanças, pilha de repetição do NSUndoManager nunca é povoada.

Assim, disableUndoRegistration Nunca chamada.

Outras dicas

Na verdade, desde que você chama enableUndoRegistration antes de ambos -undo e -redo (e disableUndoRegistration depois deles), você pode conseguir o que foram depois.

Eu acredito que você só estavam chamando permitir UndoRegistration (/ desativar) antes e depois das alterações aos seus objetos gerenciados. Isso significa que seu 'desfazer' não foi registrado com o gerenciador de reversão e, portanto, você não poderia 'refazer' it.

Eu chamei disableUndoManager mantendo "Redo" habilitado. Para fazer isso eu subclasse NSUndoManager e incluiu este método:

-(void) undo
{
  [[appDelegate managedObjectContext] processPendingChanges];
  [self enableUndoRegistration];
  [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate date]];
  [super undo];
  [[appDelegate managedObjectContext] processPendingChanges];
  [self disableUndoRegistration];
}

Como afirmado por Stefanf em NSUndoManager, Núcleo de Dados e seletiva undo / redo : "NSUndoManager aguarda o próximo ciclo de loop de execução até que registra suas alterações"

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top