Interceptar deshacer mientras edita una vista de tabla basada en células
-
26-10-2019 - |
Pregunta
Me gustaría interceptar o deshabilitar CMD-Z/Shift-CMD-Z durante una sesión de edición de texto para una celda de vista de tabla.
Es una vista de tabla basada en celdas con una serie de columnas cuyos valores se afectan entre sí, de modo que el relleno en algunas columnas llenará otras automáticamente. Cuando el usuario presiona CMD-Z en el medio de una sesión de edición, el administrador de deshacer puede cambiar la propiedad que se está editando actualmente, con resultados confusos para el usuario.
Aquí hay un ejemplo:
Paso 1: Tipos de usuario ".030" en la segunda columna:
Paso 2: la pestaña Presiones de usuario, el modelo actualiza automáticamente las columnas tres, cuatro y cinco:
Paso 3: El usuario presiona CTRL-Z, el modelo deshace cambios en las columnas dos, tres, cuatro y cinco, pero la sesión de edición aún está en progreso, por lo que el valor antiguo se muestra en la columna tres:
Paso 4: Sin escribir nada, la pestaña Presiones de usuario que cancela la edición, y el valor de la columna tres desaparece:
No está sucediendo nada realmente "mal", pero es confuso.
Cuando se edita una de las células, solo quiero interceptar CMD-Z y Shift-CMD-Z e ignorarlas. Creo que debería estar anulando -keyDown:
en lo que sea el primer respondedor durante esa edición. Pero, ¿qué es eso? La vista de la tabla no obtiene esos eventos clave en absoluto, y la célula tampoco es un respondedor.
Solución
Encontró una solución de trabajo. En mi NSTableView
subclase:
// Disable undo and redo while table's field editors have first responder status
-(BOOL)validateMenuItem:(NSMenuItem *)menuItem {
if (self != self.window.firstResponder)
if (@selector(undo:) == menuItem.action || @selector(redo:) == menuItem.action)
return NO;
return YES;
}
// Intercept undo events while table's field editors have first responder status
-(IBAction)undo:(id)sender {
if (self != self.window.firstResponder)
[self noResponderFor:_cmd];
else
[self.nextResponder tryToPerform:@selector(undo:) with:sender];
}