Tengo una vista personalizada dentro de UIBarButtonItem
, configurada llamando -initWithCustomView
. El elemento del botón de la barra se visualiza bien, pero cuando lo toco, no invoca la acción en mi objeto de destino.
Aquí está mi código:
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"someImage.png"]];
UIBarButtonItem *bbItem = [[UIBarButtonItem alloc] initWithCustomView:imageView];
self.navigationItem.leftBarButtonItem = bbItem;
[imageView release];
[bbItem setTarget:self];
[bbItem setAction:@selector(deselectAll)];
iphone
ios
objective-c
cocoa-touch
Jacob Relkin
fuente
fuente
UIBarButtonItem
heredaUIBarItem
y,NSObject
por lo tanto, no sabe nada sobre toques. Sería bueno si los documentos mencionaran que las propiedadesaction
ytarget
solo se aplican si la vista personalizada es un UIButton.Tuve el mismo problema, pero era reacio a usar una vista en
UIButton
lugar de una personalizada para miUIBarButtonItem
(según la respuesta de Drawonward).Alternativamente, puede agregar un
UIGestureRecognizer
a la vista personalizada antes de usarlo para inicializarUIBarButtonItem
; esto parece funcionar en mi proyecto.Así es como modificaría su código original:
UIImageView *SOCImageView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"cancel_wide.png"]]; UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(deselectAll:)]; [SOCImageView addGestureRecognizer:tapGesture]; SOItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:SOCImageView] autorelease]; [tapGesture release]; [SOCImageView release];
fuente
Así es como lo hago funcionar:
UIButton* infoButton = [UIButton buttonWithType: UIButtonTypeInfoLight]; [infoButton addTarget:self action:@selector(displayAboutUs) forControlEvents:UIControlEventTouchDown]; UIBarButtonItem* itemAboutUs =[[UIBarButtonItem alloc]initWithCustomView:infoButton]; …
fuente
Así es como implementé el UIButton dentro del UIBarButtonItem:
UIButton *logoButton = [UIButton buttonWithType:UIButtonTypeCustom]; [logoButton setImage: [UIImage imageNamed:@"icon.png"] forState:UIControlStateNormal]; logoButton.frame = CGRectMake(0, 0, 30, 30); [logoButton addTarget:self action:@selector(showAbout:) forControlEvents:UIControlEventTouchUpInside]; UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:logoButton]; self.navigationItem.rightBarButtonItem = barItem; [barItem release];
fuente
Tuve un problema similar. E inicialmente seguí la ruta sugerida por @drawnonward, pero luego tuve problemas cuando intenté que mi acción presentara un controlador popover en un iPad: usar un UIButton integrado como una vista personalizada significa que UIButton es el remitente del evento, y El método presentPopoverFromBarButtonItem: del controlador popover se bloquea cuando intenta enviarle mensajes que solo son apropiados para UIBarButtonItems reales.
La solución que encontré finalmente fue robar la imagen que quería usar (el icono de "información") de un UIButton desechable y construir mi UIBarButtonItem de la siguiente manera:
// Make the info button use the standard icon and hook it up to work UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; UIBarButtonItem *barButton = [[[UIBarButtonItem alloc] initWithImage:infoButton.currentImage style:UIBarButtonItemStyleBordered target:self action:@selector(showInfo:)] autorelease];
El uso de este inicializador produce un botón de barra cuyo objetivo y selector realmente funcionan. También es más fácil que envolver la imagen en una vista personalizada, pero eso es solo glaseado.
fuente
Si no desea conformarse con un UIImage y tiene una vista personalizada en su elemento barbutton, configure un reconocedor de gestos de toque en la propiedad de vista personalizada de su elemento barbutton
let tap = UITapGestureRecognizer(target: self, action: #selector(goProButtonPressed)) deviceStatusBarButtonItem.customView?.addGestureRecognizer(tap)
fuente
Jacob, todo se ve bien, sin embargo, es posible que no hayas proporcionado el selector correcto.
¿Puedes verificar que tu acción esté realmente declarada?
- (void) deselectAll;
y no
- (void) deselectAll:(id)sender;
Si es el último, deberá configurar la acción en
@selector(deselectAll:)
. (observe el punto y coma para que coincida con la declaración del método)Además, puede ser nulo
IBAction
, pero eso no es relevante para este problema que está teniendo.fuente
deselectAll
que no está siendo llamado? Al establecer un punto de interrupción del depurador, ¿o simplemente no ve los resultados esperados?Swift 3. Tuve un problema similar en el que tenía una vista personalizada dentro del elemento del botón de la barra. Para que el grifo funcione, asigné un gesto a la vista y configuré la acción. La vista tenía que ser una salida para asignarle. Al hacer esto, funcionó con la vista personalizada.
Establecer el gesto como variable de clase
@IBOutlet weak var incidentView: UIView! let incidentTap = UITapGestureRecognizer()
En viewDidLoad
incidentTap.addTarget(self, action: #selector(self.changeIncidentBarItem)) incidentView.addGestureRecognizer(incidentTap)
fuente
Swift 3 : A continuación se muestra mi implementación completa para la personalización de botones y el manejo de eventos.
override func viewDidLoad() { super.viewDidLoad() let button = UIButton.init(type: .custom) button.setTitle("Tester", for: .normal) button.setTitleColor(.darkGray, for: .normal) button.layer.borderWidth = 1 button.layer.cornerRadius = 5 button.layer.borderColor = UIColor.darkGray.cgColor button.addTarget(self, action: #selector(self.handleButton), for: .touchUpInside) self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if let button = self.navigationItem.rightBarButtonItem?.customView { button.frame = CGRect(x:0, y:0, width:80, height:34) } } func handleButton( sender : UIButton ) { // It would be nice is isEnabled worked... sender.alpha = sender.alpha == 1.0 ? 0.5 : 1.0 }
Espero que esto ayude
fuente
¿Su vista personalizada se alimenta de eventos táctiles o los transmite a la vista de padres?
fuente
UIImageView
. Entonces, no está comiendo ningún evento, no.Para facilitar el trabajo, creé una categoría en UIBarButtonItem que se ve así:
@implementation UIBarButtonItem (CustomButtonView) - (void)setButtonImage:(UIImage *)image { UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setBackgroundImage:image forState:UIControlStateNormal]; [button sizeToFit]; [button addTarget:self.target action:self.action forControlEvents:UIControlEventTouchUpInside]; self.customView = button; } - (UIImage *)buttonImage { return [(UIButton *)self.customView imageForState:UIControlStateNormal]; } @end
En su código de cliente, simplemente use:
myBarButtonItem.buttonImage = [UIImage imagedNamed:@"image_name"];
Hecho de esta manera, aún puede conectar sus objetivos y acciones en IB (introducir tanta configuración de UI en IB como pueda es algo bueno).
fuente