iphone objective-c cocoa-touch ipad uimenucontroller

iphone - UIMenuController no aparece



objective-c cocoa-touch (7)

El siguiente es un ejemplo de trabajo completo comentado ...

Ver el archivo de encabezado de subclase

#import <Foundation/Foundation.h> @interface MenuControllerSupportingView : UIView { } @end

Ver el archivo fuente de la subclase

#import "MenuControllerSupportingView.h" @implementation MenuControllerSupportingView //It''s mandatory and it has to return YES then only u can show menu items.. -(BOOL)canBecomeFirstResponder { return YES; } -(void)MenuItemAClicked { NSLog(@"Menu item A clicked"); } -(void)MenuItemBClicked { NSLog(@"Menu item B clicked"); } -(void)MenuItemCClicked { NSLog(@"Menu item C clicked"); } //It''s not mandatory for custom menu items -(BOOL)canPerformAction:(SEL)action withSender:(id)sender { if(action == @selector(MenuItemAClicked)) return YES; else if(action == @selector(MenuItemBClicked)) return YES; else if(action == @selector(MenuItemCClicked)) return YES; else return NO; }

ver el archivo de encabezado del controlador

#import <UIKit/UIKit.h> @interface ViewController1 : UIViewController @end

ver el archivo fuente del controlador

#import "ViewController1.h" #import "MenuControllerSupportingView.h" @interface ViewController1 () { MenuControllerSupportingView *vu; } @end @implementation ViewController1 - (void)viewDidLoad { [super viewDidLoad]; vu=[[SGGI_MenuControllerSupportingView alloc]initWithFrame:CGRectMake(0,0,768,1024)]; [self.view addSubview:vu]; UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom]; [btn setFrame:CGRectMake(200,200,200,30)]; [btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; [btn setTitle:@"Show" forState:UIControlStateNormal]; [btn addTarget:self action:@selector(SHowMenu) forControlEvents:UIControlEventTouchUpInside]; [vu addSubview:btn]; } -(void)SHowMenu { UIMenuController *menucontroller=[UIMenuController sharedMenuController]; UIMenuItem *MenuitemA=[[UIMenuItem alloc] initWithTitle:@"A" action:@selector(MenuItemAClicked)]; UIMenuItem *MenuitemB=[[UIMenuItem alloc] initWithTitle:@"B" action:@selector(MenuItemBClicked)]; UIMenuItem *MenuitemC=[[UIMenuItem alloc] initWithTitle:@"C" action:@selector(MenuItemCClicked)]; [menucontroller setMenuItems:[NSArray arrayWithObjects:MenuitemA,MenuitemB,MenuitemC,nil]]; //It''s mandatory [vu becomeFirstResponder]; //It''s also mandatory ...remeber we''ve added a mehod on view class if([vu canBecomeFirstResponder]) { [menucontroller setTargetRect:CGRectMake(10,10, 0, 200) inView:vu]; [menucontroller setMenuVisible:YES animated:YES]; } } -(void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end

En la clase de Vista, si escribe, devuelva SÍ solo en CanPerformAction , verá todos los elementos de menú predeterminados, como el símbolo de la cámara, cortar, copiar, etc.

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender { return YES; }

si quieres mostrar algo así como una cámara solo, entonces

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender { if(action==@selector(_insertImage:)) return YES; else return NO; }

si quieres saber sobre todas las acciones, entonces

visita el link

Intento crear un UIMenuController personalizado y mostrarlo en mi vista. Aquí está mi código:

UIMenuController *menuController = [UIMenuController sharedMenuController]; UIMenuItem *listMenuItem = [[UIMenuItem alloc] initWithTitle:@"List" action:@selector(addList:)]; [menuController setMenuItems:[NSArray arrayWithObject:listMenuItem]]; [menuController setTargetRect:CGRectMake(50.0, 50.0, 0, 0) inView:self.view]; [menuController setMenuVisible:YES animated:YES]; [listMenuItem release];

No hay errores ni excepciones, pero el controlador de menú simplemente no aparece.


En Swift 3.0 -

En mi caso, quería que el VC preseleccionara el texto en un TextView y mostrara un menú personalizado para que el usuario actúe en esa selección. Como lo menciona Kalle , el orden es muy importante, especialmente haciendo que setMenuVisible último.

En VC, viewDidLoad :

menuCont = UIMenuController.shared let menuItem1: UIMenuItem = UIMenuItem(title: "Text", action: #selector(rtfView.textItem(_:))) let menuItems: NSArray = [menuItem1] menuCont.menuItems = menuItems as? [UIMenuItem]

En VC, cuando el usuario pulsa un botón:

@IBAction func pressed(_ sender: Any) { self.textView.selectedRange = NSMakeRange(rangeStart, rangeLength) self.textView.becomeFirstResponder() menuCont.setTargetRect(CGRect.zero, in: self.textView) menuCont.setMenuVisible(true, animated: true) }

Finalmente, en la subclase de TextView:

class rtfView: UITextView { override var canBecomeFirstResponder: Bool { return true } override func canPerformAction(_ action: Selector, withSender sender: Any!) -> Bool { if (action == #selector(textItem(_:))) { return true } else { return false } } }


En caso de que alguien tenga este problema específicamente (y aleatoriamente) con iOS6: es posible que desee ver este SO relacionado con tener habilitada la selección de voz en el dispositivo (Configuración -> General -> Accesibilidad -> Selección de voz: activada). Un pequeño número de mis usuarios no pudieron ver los UIMenuItems personalizados y esta fue la causa.


La respuesta menciona tres cosas, pero para ser exigente, hay seis:

  1. El manejador de menú debe ser un UIView. Si no es así, "se -becomeFirstResponder error".
  2. El manejador de menú debe tener userInteractionEnabled = YES
  3. El manejador de menú debe estar en la jerarquía de vista y su propiedad -window debe ser la misma que la ventana para la vista en el argumento inView: .
  4. -canBecomeFirstResponder implementar -canBecomeFirstResponder y devolver YES .
  5. [handler becomeFirstResponder] llamar a [handler becomeFirstResponder] , antes de que se llame [handler becomeFirstResponder] [menu setTargetRect:inView:] , o este último fallará.
  6. [menu setTargetRect:inView] llamar al [menu setTargetRect:inView] (al menos una vez) y al [menu setMenuVisible:animated:] .

En particular, los puntos 1-3 anteriores me dieron. Quería una clase de manejador de menú personalizado que fuera un UIResponder al principio, lo que provocaba que -becomeFirstResponder devolviera NO ; luego fue un UIView , que falló, luego intenté hacer que fuera un UIButton que funcionó, pero solo porque userInteractionEnabled predeterminado en YES para los botones y NO para UIView s.



tal vez porque CGRectMake(50.0, 50.0, 0, 0) crea un CGRect con width = 0 y height = 0 ?

vítores, anka


UIMenuController es visible en cualquier vista solo si la vista es el primero en responder y

- (BOOL)canPerformAction método - (BOOL)canPerformAction devuelve YES

Por lo tanto, si su controlador de menú se muestra al hacer clic en el botón, la primera línea en la acción del botón debe ser [self becomeFirstResponder] . NOTA: aquí está la vista que presentará los menús.

Si sus menús se muestran con un gesto prolongado, agregue longPressGesture a UIView y en el evento longpress antes de escribir

[menuController setTargetRect:CGRectMake(50.0, 50.0, 0, 0) inView:self.view]; [menuController setMenuVisible:YES animated:YES];

escribe [self becomeFirstResponder];

Luego sigue los pasos mencionados por OZ.