Estaba usando iOS 6.1 anteriormente, pero ahora me cambié 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 de la barra del botón derecho 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 elementos del botón de la barra izquierda y derecha en la barra de navegación.
Gracias por adelantado.
ios
iphone
ios7
uinavigationbar
uibarbuttonitem
Salman Zaidi
fuente
fuente
Respuestas:
También estaba enfrentando este problema. También tengo la sensación de que en iOS 7 hay más espacio. Y me di cuenta de que esto es aproximadamente 10 puntos más. Normalmente utilizo espacios negativos cuando quiero
LeftBarItemButton
empezar desde el borde. Esto también puede resultarle útil.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];
fuente
Basado en @C_X su respuesta, he creado una categoría que agrega y posiciona el UIBarButtonItem según 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 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.fuente
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)
ACTUALIZACIÓN Swift 2.2:
Para Swift 2.2, el
action: Selector
método ha cambiado y debe escribirse de la siguiente maneracaptureButton.addTarget(self, action: #selector(YourViewController.showCaptureDetailsForm(_:)), forControlEvents: .TouchUpInside)
fuente
Esta es mi solución para
Swift 3.0
:rightBtn.imageInsets = UIEdgeInsets(top: 0, left: -13.0, bottom: 0, right: 13.0) self.navigationItem.rightBarButtonItem = rightBtn
fuente
Para corregir este error, debe crear una subclase
UIButton
para poder anularalignmentRectInsets
. Según mis pruebas, deberá devolver unUIEdgeInsets
con un desplazamiento derecho positivo o un desplazamiento izquierdo positivo, según la posición del botón. Estos números no tienen sentido para mí (al menos uno de ellos debería ser negativo, según 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
.fuente
Siguiendo el ejemplo de smek, hice una categoría pero la modifiqué para proporcionar compatibilidad con versiones anteriores en lugar de con versiones posteriores. Configuro todo para que funcione como quiero en iOS 7 y luego, si el usuario está ejecutando algo más bajo, empiezo a estropear las 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
UIViewController
subclase delgada de la que heredan todos mis controladores de 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 cuenta de que estoy comprobando la versión del sistema operativo dos veces (una
INFViewController
y otra vez en la categoría), la dejé en la categoría en caso de que quiera usarla como única en cualquier parte del proyecto.fuente
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, requiredButton /* this will be the button which you actually need */]
fuente
As of iOS 11 wont accept negative space width, in order to align the bar button items to the margin, I have used the below code. override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() for view in (self.navigationController?.navigationBar.subviews)! { view.layoutMargins = UIEdgeInsets.zero } }
fuente
Swift 3:
let negativeSpacer:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil) negativeSpacer.width = -10 self.navigationItem.leftBarButtonItems = [negativeSpacer, yourBarButtonItem]
fuente
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)
fuente
override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() // to remove navigation bar extra margin for view in (self.navigationController?.navigationBar.subviews)! { view.layoutMargins = UIEdgeInsets.zero } }
let rightButton = UIButton(frame: CGRect(x: 0, y: 0, width: 17, height: 20)) rightButton.setImage(UIImage(named: "ic_cart"), for: .normal) let rightBarButtomItem = UIBarButtonItem(customView: rightButton) let spacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: nil, action: nil) spacer.width = 28 //This will add extra margin on right side navigationItem.rightBarButtonItems = [spacer,rightBarButtomItem]
fuente
Creo que debe usar un botón personalizado con una
UIButton
subclase 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, pruebe con el otro.fuente
trabajó para mi
fuente
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];
fuente