uinavigationcontroller uibutton ios7 uibarbuttonitem

uinavigationcontroller - La alineación de UIBarButtonItem personalizada está desactivada con iOS7



uibutton (4)

Así que tengo el mismo problema que muchos otros están experimentando al crear un UIBarButtonItem con un UIButton como una vista personalizada.

Básicamente, el botón es de aproximadamente 10 píxeles a la izquierda o la derecha. Cuando uso un elemento BarButtonIt regular sin una vista personalizada, esto no sucede.

Esta publicación proporcionó una solución parcial: UIBarButton con vista personalizada

Aquí está mi código que he creado subclasificando UIButton (como se indica en la otra publicación)

- (UIEdgeInsets)alignmentRectInsets { UIEdgeInsets insets; if ([self isLeftButton]) { insets = UIEdgeInsetsMake(0, 9.0f, 0, 0); } else { // IF ITS A RIGHT BUTTON insets = UIEdgeInsetsMake(0, 0, 0, 9.0f); } return insets; } - (BOOL)isLeftButton { return self.frame.origin.x < (self.superview.frame.size.width / 2); }

Esto funciona muy bien, pero cuando vuelvo a colocar un controlador de vista desde el controlador de navegación en esta vista principal, el botón todavía está colocado incorrectamente durante aproximadamente .3 segundos, y luego encaja en el recuadro correcto.

Esta es una gran monstruosidad y no tengo idea de cómo evitar que se rompa de esa manera. ¿Alguna idea? ¡Gracias!


Alternativamente, puede ajustar los marcos de los contenidos de su vista personalizada (-5 para las subvistas a la izquierda, +5 para las subvistas a la derecha), y siempre que su vista personalizada no tenga clipsToBounds configurados en YES se clipsToBounds . No es la más limpia, pero otras soluciones sugeridas pueden ser incluso más intrépidas de IMO.

Las subvistas aparecerán cortadas por 5 puntos en IB, pero el contenido completo se mostrará cuando ejecute la aplicación en el simulador.


No es un gran fanático de subclasificar UIButton o método swizzling de la respuesta de Marius: https://.com/a/19317105/287403

Solo utilicé una envoltura simple y moví la x del marco del botón en una dirección negativa hasta que encontré la posición correcta. El toque del botón también parece estar bien (aunque puede ampliar el ancho del botón para que coincida con el desplazamiento negativo si lo necesita).

Aquí está el código que utilizo para generar un nuevo botón de retroceso:

- (UIBarButtonItem *) newBackButton { // a macro for the weak strong dance @weakify(self); UIButton *backButton = [[UIButton alloc] init]; [backButton setTitle:@"Back" forState:UIControlStateNormal]; backButton.titleLabel.font = [UIFont systemFontOfSize:17]; CGFloat width = [@"Back" boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX) options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:17]} context:nil].size.width + 27; backButton.frame = CGRectMake(-17.5, 0, width + 17.5, 44); [backButton setImage:[UIImage imageNamed:@"UINavigationBarBackIndicatorDefault"] forState:UIControlStateNormal]; [backButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 14, 0, 0)]; [backButton setTitleColor:mTCOrangeColor forState:UIControlStateNormal]; backButton.contentEdgeInsets = UIEdgeInsetsZero; backButton.imageEdgeInsets = UIEdgeInsetsZero; [backButton addEventHandler:^(id sender) { // a macro for the weak strong dance @strongify(self); // do stuff here } forControlEvents:UIControlEventTouchUpInside]; UIView *buttonWrapper = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, 44)]; [buttonWrapper addSubview:backButton]; return [[UIBarButtonItem alloc] initWithCustomView:buttonWrapper]; }


No he probado este código para varios elementos del botón de navegación, pero parece que funciona para botones individuales. He sobrescrito la barra UINavigation y su método layoutSubviews.

Primero, se define una constante para el desplazamiento horizontal en la parte superior del archivo. Modificar es como desees:

static CGFloat const kNavBarButtonHorizontalOffset = 10;

layoutSubviews:

- (void)layoutSubviews{ [super layoutSubviews]; //Do nothing on iOS6 if ( ![[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f){return;} UINavigationItem * navigationItem = [self topItem]; for(UIBarButtonItem * item in [navigationItem rightBarButtonItems]){ UIView * subview = [item customView]; CGFloat width = CGRectGetWidth(subview.frame); CGRect newRightButtonRect = CGRectMake(CGRectGetWidth(self.frame) - width - kNavBarButtonHorizontalOffset, CGRectGetMinY(subview.frame), width, CGRectGetHeight(subview.frame)); [subview setFrame:newRightButtonRect]; } for(UIBarButtonItem * item in [navigationItem leftBarButtonItems]){ UIView * subview = [item customView]; CGRect newRightButtonRect = CGRectMake(kNavBarButtonHorizontalOffset, CGRectGetMinY(subview.frame), CGRectGetWidth(subview.frame), CGRectGetHeight(subview.frame)); [subview setFrame:newRightButtonRect]; } }


Tuve el mismo problema que tú y muchos otros. Después de mucho tiempo tratando de arreglarlo, finalmente lo hice. Esta es la categoría que debe incluir en su archivo * -Prefix.pch. ¡Y eso es todo!

UINavigationItem + iOS7Spacing.h

#import <Foundation/Foundation.h> @interface UINavigationItem (iOS7Spacing) @end

UINavigationItem + iOS7Spacing.m

#import "UINavigationItem+iOS7Spacing.h" #import <objc/runtime.h> @implementation UINavigationItem (iOS7Spacing) - (BOOL)isIOS7 { return ([[[UIDevice currentDevice] systemVersion] compare:@"7" options:NSNumericSearch] != NSOrderedAscending); } - (UIBarButtonItem *)spacer { UIBarButtonItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; space.width = -11; return space; } - (void)mk_setLeftBarButtonItem:(UIBarButtonItem *)leftBarButtonItem { if ([self isIOS7] && leftBarButtonItem) { [self mk_setLeftBarButtonItem:nil]; [self mk_setLeftBarButtonItems:@[[self spacer], leftBarButtonItem]]; } else { [self mk_setLeftBarButtonItem:leftBarButtonItem]; } } - (void)mk_setLeftBarButtonItems:(NSArray *)leftBarButtonItems { if ([self isIOS7] && leftBarButtonItems && leftBarButtonItems.count > 0) { NSMutableArray *items = [[NSMutableArray alloc] initWithCapacity:leftBarButtonItems.count + 1]; [items addObject:[self spacer]]; [items addObjectsFromArray:leftBarButtonItems]; [self mk_setLeftBarButtonItems:items]; } else { [self mk_setLeftBarButtonItems:leftBarButtonItems]; } } - (void)mk_setRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem { if ([self isIOS7] && rightBarButtonItem) { [self mk_setRightBarButtonItem:nil]; [self mk_setRightBarButtonItems:@[[self spacer], rightBarButtonItem]]; } else { [self mk_setRightBarButtonItem:rightBarButtonItem]; } } - (void)mk_setRightBarButtonItems:(NSArray *)rightBarButtonItems { if ([self isIOS7] && rightBarButtonItems && rightBarButtonItems.count > 0) { NSMutableArray *items = [[NSMutableArray alloc] initWithCapacity:rightBarButtonItems.count + 1]; [items addObject:[self spacer]]; [items addObjectsFromArray:rightBarButtonItems]; [self mk_setRightBarButtonItems:items]; } else { [self mk_setRightBarButtonItems:rightBarButtonItems]; } } + (void)mk_swizzle:(SEL)aSelector { SEL bSelector = NSSelectorFromString([NSString stringWithFormat:@"mk_%@", NSStringFromSelector(aSelector)]); Method m1 = class_getInstanceMethod(self, aSelector); Method m2 = class_getInstanceMethod(self, bSelector); method_exchangeImplementations(m1, m2); } + (void)load { [self mk_swizzle:@selector(setLeftBarButtonItem:)]; [self mk_swizzle:@selector(setLeftBarButtonItems:)]; [self mk_swizzle:@selector(setRightBarButtonItem:)]; [self mk_swizzle:@selector(setRightBarButtonItems:)]; } @end

Categoría de UINavigationItem + iOS7Spacing en GitHub