ios cocoa-touch uimenucontroller

ios - ¿Cómo se puede eliminar REALMENTE Copy from UIMenuController?



cocoa-touch (6)

Al parecer, solía haber una manera fácil de evitar que apareciera la etiqueta "Más ..." en UIMenuController cuando agregaba más de un elemento de menú personalizado. Solo tenía que eliminar todos los elementos del menú del sistema. Hubo incluso una solución aquí para seguir teniendo copias. Solo tenía que implementar un comando de copia personalizado usando un selector diferente y luego anular canPerformAction: withSender: para no mostrar la copia 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 menos en una subclase UIWebView). canPerformAction: withSender: se llama para cada elemento del menú del sistema excepto copia: por lo que el resultado es que siempre se muestra el elemento del menú de copia del sistema. Esto significa que si tiene más de un elemento de menú personalizado, siempre estarán ocultos detrás de "Más ..."

Entonces, ¿hay alguna forma de eliminar realmente el elemento de copia del sistema o alguna forma alternativa de evitar que los elementos del menú 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 "copiar:":

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>.


Puede dibujar su propio menú en lugar de usar UIMenuController. De esta forma, puede tener tantos elementos como quiera mostrar al mismo tiempo sin usar Otro.


La técnica a la que vinculó parece funcionar. Implementé una subclase UIWebView con estos métodos, 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 sharedMenuController] 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; }


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

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

Supongo que puedes generar la UI por el guión gráfico. No todos los controles en el guión gráfico tienen su propia clase. Puede definir una clase para el control de respuesta y reescribir su método canPerformAction.


para ios> = 5.1 canPerformAction: (SEL) action withSender: (id) el remitente ya no funciona.

Si está bien con solo deshabilitar pegar acción aquí hay un método:

agregue UITextFieldDelegate para ver el controlador e implemente 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 por cada acción (significa que probablemente el usuario esté pegando algo) no lo acepte en el campo de texto.

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


Aquí hay una solución para iOS5.x que funciona para mí. Es por Josh Garnham, sugiriendo crear una categoría UIWebBrowserView para capturar la copia :, 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 cuenta solo FTR: hay un pequeño error tipográfico en esa excelente página web. Aquí es exactamente cómo lo haces. Apple lo rechazará al 100%. Hacer una categoría

(Debe escribir "UIWebBrowserView" ya que Xcode no abrirá las clases privadas). Texto completo de los archivos .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 el registro, un "solo clic" aún mostrará las molestas sugerencias de corrector ortográfico. Pero, de lo contrario, elimina totalmente el menú de doble clic-contexto, Apple lo rechaza al 100%.


La respuesta de Lemnar es correcta. Implementar una subclase de UIWebView funciona bien. Este ejemplo está bien para una UITextView. Para un UIWebView, crea una subclase 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

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

ACTUALIZAR :

Si desea deshabilitar "copiar" 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]; }