Cómo editar espacios vacíos de UIBarButtonItem izquierdo y derecho en UINavigationBar

Estaba usando iOS 6.1 anteriormente, pero ahora me mudé a iOS 7. Junto con otros problemas, he observado que en mi barra de navigation, el espacio izquierdo del elemento del button de la barra izquierda y el espacio vacío derecho del elemento de la barra de button derecho son bastante más en IOS 7 que en iOS 6.

Necesito saber ¿hay alguna manera de networkingucir los espacios vacíos de los elementos del button izquierdo y derecho en la barra de navigation?

Gracias por adelantado.

También me enfrenté a este problema. También tengo sentimientos de que en iOS 7 hay más espacio. Y me di count de que esto es aproximadamente 10 puntos más. Usualmente uso espacios negativos cuando quiero que LeftBarItemButton comience desde el borde. Esto también puede ser útil para usted.

 UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; negativeSpacer.width = -16; // it was -6 in iOS 6 [self.navigationItem setLeftBarButtonItems:@[negativeSpacer, requinetworkingButton /* this will be the button which you actually need */] animated:NO]; 

Basado en @C_X su respuesta he creado una categoría que agrega y posiciona el UIBarButtonItem basado en la versión de 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 controller de vista ahora puede usar [self.navigationItem addLeftBarButtonItem:leftBarButtonItem]; y [self.navigationItem addRightBarButtonItem:rightBarButtonItem];

También he intentado subclasificar UIButton y override -alignmentRectInsets pero esto me dio problemas con las transiciones entre vistas.

Para Swift 2.0, esta fue mi solución para get el siguiente efecto …

(los valores reales pueden ser diferentes, dependiendo de su situación)

introduzca la descripción de la imagen aquí

 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)

Siguiendo la pista de smek hice una categoría pero la modifiqué para proporcionar compatibilidad hacia atrás en lugar de hacia adelante. Configuré todo para funcionar como lo quiero en iOS 7 y luego, si el usuario está ejecutando algo más bajo, empiezo a mezclarme con 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 get esto globalmente, tengo una subclass del UIViewController delgada que UIViewController todos los controlleres de mi vista.

 @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 count de que estoy revisando la versión del sistema operativo dos veces (una vez en INFViewController y otra vez en la categoría), lo dejé en la categoría en caso de que quiera usar esto como una sola vez en cualquier parte del proyecto.

Para corregir este error, debe subclass el UIButton para que pueda anular alignmentRectInsets . A partir de mis testings, necesitará devolver un UIEdgeInsets con un desplazamiento positivo correcto o un desplazamiento positivo positivo, dependiendo de la position del button. Estos numbers no tienen sentido para mí (al less 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 bash ajustar alignmentRectInsets .

para rápido puedes hacer esto

 var negativeSpace:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil) negativeSpace.width = -17.0 self.navigationItem.rightBarButtonItems = [negativeSpace, requinetworkingButton /* this will be the button which you actually need */] 

Swift 3:

 let negativeSpacer:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil) negativeSpacer.width = -10 self.navigationItem.leftBarButtonItems = [negativeSpacer, yourBarButtonItem] 

Esta es mi solución para swift 3.0:

rightBtn.imageInsets = UIEdgeInsets (arriba: 0, a la izquierda: -13.0, abajo: 0, a la derecha: 13.0) self.navigationItem.rightBarButtonItem = rightBtn

Creo que necesitas usar un button personalizado con una subclass UIButton , y en tu subclass, override -alignmentRectInsets . Olvidé si necesitas un valor positivo o negativo para el borde apropiado para que cambie correctamente, pero si uno no funciona, testing con el otro.

Buena decisión, muchas gracias! Necesitaba agregar solo dos elementos al lado izquierdo del encabezado de navigation. 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 shanetworkingApplication] 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:UIBarButtonItemStyleBordenetworking target:self action:@selector(showStarnetworking)]; 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]; 

Swift 3.1

Para dar espacio negativo al elemento del button izquierdo de la barra:

  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)