objective c - No se puede hacer que UIMenuController muestre elementos personalizados
objective-c uicollectionview (3)
Por lo tanto, no estoy seguro de si estoy haciendo algo mal aquí, pero tengo un UIViewController que tiene un UICollectionView en él. En el método viewDidLoad de viewDidLoad
, hago lo siguiente: no agrega ningún elemento de menú personalizado a la ventana emergente que aparece.
UIMenuItem *removeItem = [[UIMenuItem alloc] initWithTitle:@"Remove" action:@selector(handleRemoveItem:)];
UIMenuItem *duplicateItem = [[UIMenuItem alloc] initWithTitle:@"Duplicate" action:@selector(handleDuplicateItem:)];
[[UIMenuController sharedMenuController] setMenuItems:@[removeItem, duplicateItem]];
[removeItem release];
[duplicateItem release];
Establecí la collectionView:shouldShowMenuForItemAtIndexPath:
y la collectionView:canPerformAction:forItemAtIndexPath:withSender:
para devolver YES
en todas las circunstancias, pero collectionView:canPerformAction:forItemAtIndexPath:withSender:
, solo se mostrarán Cortar, Copiar y Pegar.
¿No implementé esto completamente, o no lo hice bien? Gracias de antemano por cualquier ayuda que pueda brindarse.
PD: miré tantos ejemplos como pude en google y no encontré nada que me ayudara.
Paso 1: Crear elementos de menú
UIMenuItem* miCustom1 = [[UIMenuItem alloc] initWithTitle:@"Custom 1" action:@selector(onCustom1:)];
UIMenuItem* miCustom2 = [[UIMenuItem alloc] initWithTitle: @"Custom 2" action:@selector(onCustom2:)];
Paso 2: Crea MenuController
UIMenuController* mc = [UIMenuController sharedMenuController];
Paso 3: agregar elementos al controlador de menú
mc.menuItems = [NSArray arrayWithObjects: miCustom1, miCustom2, nil];
Paso 4: Crear métodos de acción para los artículos
- (void) onCustom1: (UIMenuController*) sender
{
}
- (void) onCustom2: (UIMenuController*) sender
{
}
Paso 5: opcionalmente para configurar FirstResponder para Acciones
- (BOOL) canPerformAction:(SEL)action withSender:(id)sender
{
if ( action == @selector( onCustom1: ) )
{
return YES; // logic here for context menu show/hide
}
if ( action == @selector( onCustom2: ) )
{
return NO; // logic here for context menu show/hide
}
if ( action == @selector( copy: ) )
{
// turn off copy: if you like:
return NO;
}
return [super canPerformAction: action withSender: sender];
}
Paso 6: finalmente, muestra tu MenuController en alguna acción de botón
UIMenuController* mc = [UIMenuController sharedMenuController];
CGRect bounds = sender.view.bounds;
[mc setTargetRect: sender.view.frame inView:sender.view.superview];
[mc setMenuVisible:YES animated: YES];
Estás en lo correcto. Es imposible personalizar el menú que aparece cuando hace una pulsación larga en una celda de vista de tabla o celda de vista de colección.
Discuto el problema en mi libro:
http://www.apeth.com/iOSBook/ch21.html#_table_view_menus
Como digo allí, Copiar, Cortar y Pegar son las únicas opciones que puede tener. Deberá hacer que el menú emane de otra cosa si desea personalizarlo.
EDITAR: En la versión iOS 7 de mi libro, demuestro una forma de hacerlo. Es lo mismo para las celdas de vista de tabla y celdas de vista de colección, así que comenzaré con la solución de celda de vista de tabla. El truco es que debe implementar el método de acción en una subclase de celda . Por ejemplo, si su selector de acción personalizado es abbrev:
debe crear una subclase de la celda e implementar abbrev:
:
Esa es la única parte difícil. Luego, de vuelta en su clase de controlador, lo hace para abbrev:
exactamente lo que haría por cualquier menú. En shouldShowMenuForRowAtIndexPath:
agréguelo al menú personalizado. Luego implemente canPerformAction:
y performAction:
tal como cabría esperar (desplácese hasta el final):
Aquí está la implementación paralela para las celdas de vista de colección: la subclase de celda:
Y el controlador (desplazarse hasta el final):
Esos enfoques también se traducen en Swift (no sin cierta dificultad) en la edición iOS 8 de mi libro.
Pude implementar menús personalizados en un UICollectionViewCell siguiendo las instrucciones en este enlace ( https://.com/a/13618212/2313416 ) con algo de improvisación.
En mi UICollectionViewController, implementé los elementos de menú personalizados agregándolos al controlador de menú como en el enlace.
Luego implementé lo siguiente en UICollectionViewController:
- (BOOL)collectionView:(UICollectionView *)cv canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
return NO;
}
- (BOOL)collectionView:(UICollectionView *)cv shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)collectionView:(UICollectionView *)cv performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
NSLog(@"perform action:%@", NSStringFromSelector(action));
}
En mi UICollectionViewCell, implementé algo similar a lo siguiente:
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
if (action == @selector(onCustom1:)) {
return YES;
}
if (action == @selector(onCustom2:)) {
return YES;
}
return NO;
}
Estas acciones tienen que ser las mismas que las implementadas en el controlador de recopilación.
Si uno quiere incluir las funciones copiar o pegar, agréguelas a canPerformAction: y luego cambie collectionView :: canPerformAction: para devolver SÍ.
Puede que esta no sea la mejor manera de hacerlo, pero me ha funcionado.