¿Cómo REALMENTE eliminas copy de UIMenuController

Al parecer, solía ser una manera fácil de evitar que la label "Más …" aparezca en UIMenuController cuando agrega más de un elemento de menu personalizado. Solo tuvo que eliminar todos los elementos del menu del sistema. Incluso hubo una solución aquí para seguir teniendo trabajo de copy. Solo tuvo que implementar un command de copy personalizado utilizando un selector diferente y luego anular canPerformAction: withSender: para no mostrar la copy del sistema:

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender { if (action == @selector(copy:)) return NO; else // logic to show or hide other things } 

Lamentablemente, este método ya no funciona (al less en una subclass UIWebView). canPerformAction: withSender: se invoca para cada elemento del menu del sistema excepto la copy: por lo que el resultado es que siempre se muestra el elemento del menu de copy del sistema. Esto significa que si tiene más de un elemento de menu personalizado, siempre se ocultan detrás de "Más …"

Entonces, ¿hay alguna forma de eliminar realmente el elemento de copy del sistema o alguna otra alternativa para evitar que los elementos del menu se oculten detrás de "Más …"?

Actualizar

Este es el resultado que obtengo cuando anulo canPerformAction: withSender: observe que el método nunca se llama para la acción "copyr:":

 cannot perform action cut: with sender <UIMenuController: 0x7227d30>. cannot perform action select: with sender <UIMenuController: 0x7227d30>. cannot perform action selectAll: with sender <UIMenuController: 0x7227d30>. cannot perform action paste: with sender <UIMenuController: 0x7227d30>. cannot perform action delete: with sender <UIMenuController: 0x7227d30>. cannot perform action promptForReplace: with sender <UIMenuController: 0x7227d30>. cannot perform action _showMoreItems: with sender <UIMenuController: 0x7227d30>. cannot perform action _setRtoLTextDirection: with sender <UIMenuController: 0x7227d30>. cannot perform action _setLtoRTextDirection: with sender <UIMenuController: 0x7227d30>. can perform action customCopy: with sender <UIMenuController: 0x7227d30>. can perform action custom1: with sender <UIMenuController: 0x7227d30>. cannot perform action custom2: with sender <UIMenuController: 0x7227d30>. can perform action custom3: with sender <UIMenuController: 0x7227d30>. can perform action custom4: with sender <UIMenuController: 0x7227d30>. cannot perform action cut: with sender <UIMenuController: 0x7227d30>. cannot perform action select: with sender <UIMenuController: 0x7227d30>. cannot perform action selectAll: with sender <UIMenuController: 0x7227d30>. cannot perform action paste: with sender <UIMenuController: 0x7227d30>. cannot perform action delete: with sender <UIMenuController: 0x7227d30>. cannot perform action promptForReplace: with sender <UIMenuController: 0x7227d30>. cannot perform action _showMoreItems: with sender <UIMenuController: 0x7227d30>. cannot perform action _setRtoLTextDirection: with sender <UIMenuController: 0x7227d30>. cannot perform action _setLtoRTextDirection: with sender <UIMenuController: 0x7227d30>. 

La técnica con la que te vinculas todavía parece funcionar. Implementé una subclass UIWebView con estos methods, y solo aparecieron los elementos A y B.

 + (void)initialize { UIMenuItem *itemA = [[UIMenuItem alloc] initWithTitle:@"A" action:@selector(a:)]; UIMenuItem *itemB = [[UIMenuItem alloc] initWithTitle:@"B" action:@selector(b:)]; [[UIMenuController shanetworkingMenuController] setMenuItems:[NSArray arrayWithObjects:itemA, itemB, nil]]; [itemA release]; [itemB release]; } - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { BOOL can = [super canPerformAction:action withSender:sender]; if (action == @selector(a:) || action == @selector(b:)) { can = YES; } if (action == @selector(copy:)) { can = NO; } NSLog(@"%@ perform action %@ with sender %@.", can ? @"can" : @"cannot", NSStringFromSelector(action), sender); return can; } 

para ios> = 5.1 canPerformAction: acción (SEL) con el remitente: (id) el remitente ya no funciona.

Si está de acuerdo con simplemente desactivar la acción de pegar, aquí hay un método:

agregue UITextFieldDelegate para ver el controller e implementar un método como este

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ if(textField == txtEmailRe) return ((string.length) > 1 ? NO : YES); } 

significa que si el usuario ingresa más de un carácter para cada acción (significa que probablemente el usuario está pegando algo), no lo acepte en el campo de text.

es una buena práctica para forzar al usuario ingresar campos de text como correo electrónico y

La respuesta de lemnar es correcta. Implementar una subclass de UIWebView funciona bien. Este ejemplo es correcto para un UITextView. Para una UIWebView, cree una subclass personalizada de la siguiente manera:

 // // MyUIWebView.h // #import <UIKit/UIKit.h> @interface MyUIWebView : UIWebView @end 

Y:

 // // MyUIWebView.m // #import "MyUIWebView.h" @implementation MyUIWebView -(BOOL)canPerformAction:(SEL)action withSender:(id)sender { if (action == @selector(copy:)) return NO; else // logic to show or hide other things } @end 

Entonces, en lugar de crear una instancia de UIWebView, use MyUIWebView.

ACTUALIZACIÓN :

Si quiere deshabilitar "copyr", pero deja "definir" (y "traducir"), que puede ser útil, así es como hacerlo; reemplace canPerformAction:withSender arriba con esto:

 -(BOOL)canPerformAction:(SEL)action withSender:(id)sender { if (action == @selector(defineSelection:)) { return YES; } else if (action == @selector(translateSelection:)) { return YES; } else if (action == @selector(copy:)) { return NO; } return [super canPerformAction:action withSender:sender]; } 

Aquí hay una solución para iOS5.x que me funciona. Es por Josh Garnham, que sugiere crear una categoría UIWebBrowserView para atrapar la copy :, pegar :, definir: selectores.

http://ios-blog.co.uk/iphone-development-tutorials/rich-text-editing-highlighting-and-uimenucontroller-part-3/

 @implementation UIWebBrowserView (UIWebBrowserView_Additions) - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { return NO; } @end 

Tenga en count solo FTR: hay un pequeño error tipográfico en esa excelente página web. Aquí está precisamente cómo lo haces. Apple lo rechazará al 100%. Hacer una categoría

introduzca la descripción de la imagen aquí

(Debe ingresar "UIWebBrowserView", ya que Xcode no mostrará las classs privadas). Texto completo de los files .h y .m:

 // .h file... #import "UIWebBrowserView+Tricky.h" @interface UIWebBrowserView : UIView @end @interface UIWebBrowserView(Tricky) @end // .m file... #import "UIWebBrowserView+Tricky.h" @implementation UIWebBrowserView (Tricky) -(BOOL)canPerformAction:(SEL)action withSender:(id)sender { NSLog(@"don't let Apple see this"); return NO; } @end 

Para que conste, un "clic" seguirá apareciendo las molestas sugerencias ortográficas. Pero, de lo contrario, elimina el menu contextual de doble clic, Apple lo rechaza al 100%.

Lo siento por mi Inglés. Pero hay una idea.

Creo que el método canPerformAction se invocó muchas veces, pero lo tratas una vez. En este caso, creo que puede haber otro UI Control lo haya llamado. Por ejemplo, el control UITextView en su UIWebView.

Supongo que puede generar la UI por storyboard. No todos los controles en storyboard tienen su propia class. Puede definir una class para el control de respuesta y reescribir su método canPerformAction.

Puede dibujar su propio menu en lugar de usar UIMenuController. De esta manera, puede tener tantos elementos como desee mostrar al mismo time sin usar Otro.