Cómo editar espacios vacíos de Left, Right UIBarButtonItem en UINavigationBar
iphone ios7 (11)
Basado en @C_X su respuesta, he creado una categoría que agrega y posiciona el UIBarButtonItem basado en la versión iOS del dispositivo actual.
// UINavigationItem+Additions.h
@interface UINavigationItem (Additions)
- (void)addLeftBarButtonItem:(UIBarButtonItem *)leftBarButtonItem;
- (void)addRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem;
@end
// UINavigationItem+Additions.m
@implementation UINavigationItem (Additions)
- (void)addLeftBarButtonItem:(UIBarButtonItem *)leftBarButtonItem
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
// Add a negative spacer on iOS >= 7.0
UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
target:nil action:nil];
negativeSpacer.width = -10;
[self setLeftBarButtonItems:[NSArray arrayWithObjects:negativeSpacer, leftBarButtonItem, nil]];
} else {
// Just set the UIBarButtonItem as you would normally
[self setLeftBarButtonItem:leftBarButtonItem];
}
}
- (void)addRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
// Add a negative spacer on iOS >= 7.0
UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
target:nil action:nil];
negativeSpacer.width = -10;
[self setRightBarButtonItems:[NSArray arrayWithObjects:negativeSpacer, rightBarButtonItem, nil]];
} else {
// Just set the UIBarButtonItem as you would normally
[self setRightBarButtonItem:rightBarButtonItem];
}
}
@end
En su controlador de vista ahora puede usar [self.navigationItem addLeftBarButtonItem:leftBarButtonItem];
y [self.navigationItem addRightBarButtonItem:rightBarButtonItem];
También intenté subclasificar UIButton
y anular -alignmentRectInsets
pero esto me dio problemas con las transiciones entre vistas.
Estaba usando iOS 6.1 anteriormente, pero ahora me he movido a iOS 7. Junto con otros problemas, he observado que en mi barra de navegación, el espacio izquierdo del elemento del botón de la barra izquierda y el espacio vacío derecho del elemento del botón derecho del botón son bastante más en iOS 7 que en iOS 6.
Necesito saber si hay alguna manera de reducir los espacios vacíos de los ítems del botón de la barra izquierda, derecha en la barra de navegación?
Gracias por adelantado.
Buena decisión, muchas gracias! Necesitaba agregar solo dos elementos al lado izquierdo del encabezado de navegación. Esta es mi solución:
// Settings Button
// This trick correct spacing between two left buttons
UIBarButtonItem *settingsButtonItem = [[UIBarButtonItem alloc] init];
UIView *settingsButtonItemView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 22.0, 22.0)];
settingsButtonItem.customView = settingsButtonItemView;
UIButton *settingsButton = [UIButton buttonWithType:UIButtonTypeSystem];
settingsButton.frame = settingsButtonItemView.frame;
[settingsButton setImage:[UIImage imageNamed:@"settings"] forState:UIControlStateNormal];
settingsButton.tintColor = [[[[UIApplication sharedApplication] delegate] window] tintColor];
[settingsButton addTarget:self action:@selector(showSettings:) forControlEvents:UIControlEventTouchDown];
[settingsButtonItemView addSubview:settingsButton];
// Star Button
UIBarButtonItem *starButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"star_gray"] style:UIBarButtonItemStyleBordered target:self action:@selector(showStarred)];
starButtonItem.width = 22.0;
NSLog(@"%f", starButtonItem.width);
// Negative Spacer
// It shifts star button to the left
UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
negativeSpacer.width = -10.0;
NSArray *leftNavigtaionBarButtonItems = @[negativeSpacer, starButtonItem, settingsButtonItem];
[self.navigationItem setLeftBarButtonItems:leftNavigtaionBarButtonItems];
Creo que necesita usar un botón personalizado con una subclase UIButton
, y en su subclase, anular -alignmentRectInsets
. Olvidé si necesita un valor positivo o negativo para el borde apropiado para que cambie correctamente, pero si uno no funciona, intente con el otro.
Esta es mi solución para swift 3.0:
rightBtn.imageInsets = UIEdgeInsets (arriba: 0, izquierda: -13.0, abajo: 0, derecha: 13.0) self.navigationItem.rightBarButtonItem = rightBtn
Para Swift 2.0, esta fue mi solución para obtener el siguiente efecto ...
(los valores reales pueden ser diferentes, dependiendo de su situación)
let captureButton = UIButton()
captureButton.setTitle("CAPTURE DETAILS", forState: .Normal)
captureButton.frame = CGRectMake(0, 0, 200, 95)
captureButton.addTarget(self, action: Selector("showCaptureDetailsForm:"), forControlEvents: .TouchUpInside) // *** See update below for Swift 2.2 syntax
captureButton.setBackgroundImage(UIImage(named: "blueTopRight"), forState: .Normal)
let rightBarButton = UIBarButtonItem()
rightBarButton.customView = captureButton
let negativeSpacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
negativeSpacer.width = -25;
self.navigationItem.setRightBarButtonItems([negativeSpacer, rightBarButton ], animated: false)
Swift 2.2 ACTUALIZACIÓN:
Para Swift 2.2, la action: Selector
método action: Selector
ha cambiado y debe escribirse de la siguiente manera
captureButton.addTarget(self, action: #selector(YourViewController.showCaptureDetailsForm(_:)), forControlEvents: .TouchUpInside)
Para solucionar este error, debe subclase UIButton
para que pueda anular alignmentRectInsets
. A partir de mis pruebas, deberá devolver un UIEdgeInsets
con un desplazamiento a la derecha positivo o un desplazamiento a la izquierda positivo, dependiendo de la posición del botón. Estos números no tienen sentido para mí (al menos uno de ellos debería ser negativo, de acuerdo con el sentido común), pero esto es lo que realmente funciona:
- (UIEdgeInsets)alignmentRectInsets {
UIEdgeInsets insets;
if (IF_ITS_A_LEFT_BUTTON) {
insets = UIEdgeInsetsMake(0, 9.0f, 0, 0);
}
else { // IF_ITS_A_RIGHT_BUTTON
insets = UIEdgeInsetsMake(0, 0, 0, 9.0f);
}
return insets;
}
Un agradecimiento especial a @zev por sugerir que intente ajustar alignmentRectInsets
.
Siguiendo el ejemplo de smek, hice una categoría pero la modifiqué para proporcionar compatibilidad hacia atrás en lugar de hacia adelante. Configuro todo para que funcione como lo quiero en iOS 7 y luego, si el usuario ejecuta algo más bajo, empiezo a perder cosas.
@interface UINavigationItem (BarButtonItemSpacingSupport)
- (void)addLeftBarButtonItem:(UIBarButtonItem *)leftBarButtonItem;
- (void)addRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem;
@end
@implementation UINavigationItem (BarButtonItemSpacingSupport)
- (void)addLeftBarButtonItem:(UIBarButtonItem *)leftBarButtonItem
{
if (SYSTEM_VERSION_LESS_THAN(@"7.0")) {
// Add a spacer on when running lower than iOS 7.0
UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
target:nil action:nil];
negativeSpacer.width = 10;
[self setLeftBarButtonItems:[NSArray arrayWithObjects:negativeSpacer, leftBarButtonItem, nil]];
} else {
// Just set the UIBarButtonItem as you would normally
[self setLeftBarButtonItem:leftBarButtonItem];
}
}
- (void)addRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem
{
if (SYSTEM_VERSION_LESS_THAN(@"7.0")) {
// Add a spacer on when running lower than iOS 7.0
UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
target:nil action:nil];
negativeSpacer.width = 10;
[self setRightBarButtonItems:[NSArray arrayWithObjects:negativeSpacer, rightBarButtonItem, nil]];
} else {
// Just set the UIBarButtonItem as you would normally
[self setRightBarButtonItem:rightBarButtonItem];
}
}
@end
Y luego para obtener esto globalmente, tengo una subclase UIViewController
delgada de la que todos mis controladores de vista heredan.
@interface INFViewController : UIViewController
@end
@implementation INFViewController
- (void)viewDidLoad {
[super viewDidLoad];
if (SYSTEM_VERSION_LESS_THAN(@"7.0")) {
[self setupNavBarForPreIOS7Support];
}
}
- (void)setupNavBarForPreIOS7Support {
if (self.navigationController) {
UINavigationItem *navigationItem = self.navigationItem;
UIBarButtonItem *leftItem = navigationItem.leftBarButtonItem;
UIBarButtonItem *rightItem = navigationItem.rightBarButtonItem;
if (leftItem) {
[navigationItem addLeftBarButtonItem:leftItem];
}
if (rightItem) {
[navigationItem addRightBarButtonItem:rightItem];
}
}
}
@end
Me doy cuenta de que estoy verificando la versión del sistema operativo dos veces (una vez en INFViewController
y nuevamente en la categoría), la dejé en la categoría en caso de que quiera utilizarla como una INFViewController
única en cualquier parte del proyecto.
Swift 3:
let negativeSpacer:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil)
negativeSpacer.width = -10
self.navigationItem.leftBarButtonItems = [negativeSpacer, yourBarButtonItem]
para swift puedes hacer esto
var negativeSpace:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
negativeSpace.width = -17.0
self.navigationItem.rightBarButtonItems = [negativeSpace, requiredButton /* this will be the button which you actually need */]
Swift 3.1
Para dar espacio negativo al elemento del botón de la barra izquierda:
let backButton = UIButton.init(type: .custom)
backButton.frame = CGRect.init(x: 0, y: 0, width: 40, height: 40)
// negative space
backButton.contentEdgeInsets = UIEdgeInsets(top: 0, left: -44.0, bottom: 0, right: 0)
backButton.setImage(Ionicons.iosArrowBack.image(30, color: UIColor(hex: 0xFD6250)), for: .normal)
backButton.addTarget(self, action: #selector(InviteVC.goBack), for: .touchUpInside)
// set back button
self.navigationItem.leftBarButtonIteUIBarButtonItem.init(customView: backButton)
Yo también estaba enfrentando este problema. También tengo la sensación de que en iOS 7
hay más espacio. Y descubrí que esto es alrededor de 10
puntos más. Usualmente uso espacios negativos cuando quiero que LeftBarItemButton
comience desde el borde. Esto puede ser útil para ti también.
UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
negativeSpacer.width = -16; // it was -6 in iOS 6
[self.navigationItem setLeftBarButtonItems:@[negativeSpacer, requiredButton]; /* this will be the button which you actually need */] animated:NO];