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:
- El manejador de menú debe ser un UIView. Si no es así, "se
-becomeFirstResponder
error". - El manejador de menú debe tener
userInteractionEnabled = YES
- 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 argumentoinView:
. -
-canBecomeFirstResponder
implementar-canBecomeFirstResponder
y devolverYES
. -
[handler becomeFirstResponder]
llamar a[handler becomeFirstResponder]
, antes de que se llame[handler becomeFirstResponder]
[menu setTargetRect:inView:]
, o este último fallará. -
[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.
Tienes que hacer tres cosas:
-
-becomeFirstResponder
llamar a-becomeFirstResponder
en la vista o ver el controlador. - Su controlador de vista o vista necesita implementar
-canBecomeFirstResponder
(devolviendoYES
). - Opcionalmente, su controlador de vista o vista puede implementar
-canPerformAction:action withSender:sender
para mostrar / ocultar elementos de menú de forma individual.
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.