iOS7 rembourrage excessif des boutons de la barre de navigation

Je rencontre un espacement / espacement UIBarButtonItem excessif lorsque j’utilise les LeftBarItems et RightBarItems (voir l’image ci-dessous). Les icons utilisées sur UIBarButtonItems ne contiennent pas de remplissage supplémentaire. Donc, je voudrais savoir ce qui cause cela?

entrer la description de l'image ici

Je l’utilise pour supprimer l’espace avant le premier élément.

Cependant, il ne fonctionne pas entre des éléments système tels que UIBarButtonSystemItemAdd , uniquement avec UIBarButtonItem qui possède une image.

 @interface UIBarButtonItem (NegativeSpacer) +(UIBarButtonItem*)negativeSpacerWithWidth:(NSInteger)width; @end @implementation UIBarButtonItem (NegativeSpacer) +(UIBarButtonItem*)negativeSpacerWithWidth:(NSInteger)width { UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; item.width = (width >= 0 ? -width : width); return item; } @end 

Utilisez-le comme ceci:


 UIBarButtonItem *item0 = [UIBarButtonItem negativeSpacerWithWidth:13]; UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"sidebar.png"] style:UIBarButtonItemStylePlain target:vc action:@selector(sideMenuAction:)]; NSArray* items = @[item0, item1]; [vc.navigationItem setLeftBarButtonItems:items animated:NO]; [vc.navigationItem setLeftItemsSupplementBackButton:YES]; 

Vous pouvez déplacer l’image

 self.myBarButtonItem.imageInsets = UIEdgeInsetsMake(0, 25, 0, -25); 

Apple a silencieusement augmenté les contraintes d’espacement horizontal pour UIBarButtonItems et, malheureusement, n’a toujours pas ajouté de méthodes d’application UIA pour ajuster le positionnement horizontal de UIBarButtonItems.

La meilleure solution (qui a fonctionné pour moi) est d’emballer vos UIBarButtonItems dans un UIView en utilisant initWithCustomView: et d’ajuster les limites de cette vue personnalisée pour obtenir le positionnement souhaité. Voici une bonne réponse à cette question .

Si vous voulez aller plus loin, vous pouvez créer une catégorie sur UIBarButtonItem avec des méthodes de classe qui renvoient les boutons de barre que vous utilisez dans votre application. De cette façon, lorsque vous avez besoin d’un bouton de barre, vous pouvez appeler quelque chose comme:

 self.navigationItem.leftBarButtonItem = [UIBarButtonItem mySearchBarButtonItemWithTarget:self selector:@selector(search)]; 

Il existe deux types de boutons sur la barre de navigation dans iOS 7: bouton avec image et bouton avec texte. J’ai écrit un cours pour le faire. Voici comment:

GlobalUICommon.h:

 @interface UIBarButtonItem(CustomUIOfONE) + (UIBarButtonItem*)barItemWithImage:(UIImage*)image highlightedImage:(UIImage*)highlightedImage xOffset:(NSInteger)xOffset target:(id)target action:(SEL)action; + (UIBarButtonItem*)barItemWithTitle:(NSSsortingng*)title xOffset:(NSInteger)xOffset target:(id)target action:(SEL)action; @end 

GlobalUICommon.m:

 @implementation UIBarButtonItem(CustomUIOfONE) + (UIBarButtonItem*)barItemWithImage:(UIImage*)image highlightedImage:(UIImage*)highlightedImage xOffset:(NSInteger)xOffset target:(id)target action:(SEL)action { UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setFrame:CGRectMake(0, 0, image.size.width, image.size.height)]; [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; [button setImage:image forState:UIControlStateNormal]; [button setImage:highlightedImage forState:UIControlStateHighlighted]; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { [button setImageEdgeInsets:UIEdgeInsetsMake(0, xOffset, 0, -xOffset)]; } UIBarButtonItem *customUIBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button]; return customUIBarButtonItem; } + (UIBarButtonItem*)barItemWithTitle:(NSSsortingng*)title xOffset:(NSInteger)xOffset target:(id)target action:(SEL)action { UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setTitle:title forState:UIControlStateNormal]; [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted]; [button.titleLabel setFont:[UIFont systemFontOfSize:15]]; [button setFrame:CGRectMake(0, 0, [button.titleLabel.text sizeWithFont:button.titleLabel.font].width + 3, 24)]; [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { [button setContentEdgeInsets:UIEdgeInsetsMake(0, xOffset, 0, -xOffset)]; } UIBarButtonItem *customUIBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button]; return customUIBarButtonItem; } @end 

YourViewController.m:

Exemple de bouton avec image:

 UIBarButtonItem* leftButtomItem = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:@"yourImage"] highlightedImage:[UIImage imageNamed:@"yourImage"] xOffset:-11 target:self action:@selector(yourHandler)]; self.navigationItem.leftBarButtonItem = leftButtomItem; UIBarButtonItem* rightButtonItem = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:@"yourImage"] highlightedImage:[UIImage imageNamed:@"yourImage"] xOffset:11 target:self action:@selector(yourHandler)]; self.navigationItem.rightBarButtonItem = rightButtonItem; 

Exemple de bouton avec du texte:

 self.navigationItem.leftBarButtonItem = [UIBarButtonItem barItemWithTitle:@"yourText" xOffset:-11 target:self action:@selector(yourHandler:)]; self.navigationItem.rightBarButtonItem = [UIBarButtonItem barItemWithTitle:@"yourText" xOffset:11 target:self action:@selector(yourHandler:)]; 

C’est tout.

J’ai résolu ce problème en utilisant l’interface de storybord.

1.Sélectionnez l’ Bar item .

2.Sélectionnez l’ Size Inspector .

Ici vous pouvez trouver l’image Inset, en utilisant top , bottom ET left , à right vous pouvez changer la position de l’élément de barre.

Comme le remarque @Luda, la solution consiste à

 self.myBarButtonItem.imageInsets = UIEdgeInsetsMake(0, 25, 0, -25); 

Cependant, @andrrs pointe également un problème ici lorsque l’encart est grand: la zone touchée. Dans ce cas, nous devons implémenter un moyen de setHitTestEdgeInsets. Voici une méthode de catégorie:

 @implementation UIButton (Extensions) @dynamic hitTestEdgeInsets; static const NSSsortingng *KEY_HIT_TEST_EDGE_INSETS = @"HitTestEdgeInsets"; -(void)setHitTestEdgeInsets:(UIEdgeInsets)hitTestEdgeInsets { NSValue *value = [NSValue value:&hitTestEdgeInsets withObjCType:@encode(UIEdgeInsets)]; objc_setAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -(UIEdgeInsets)hitTestEdgeInsets { NSValue *value = objc_getAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS); if(value) { UIEdgeInsets edgeInsets; [value getValue:&edgeInsets]; return edgeInsets; }else { return UIEdgeInsetsZero; } } - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { if(UIEdgeInsetsEqualToEdgeInsets(self.hitTestEdgeInsets, UIEdgeInsetsZero) || !self.enabled || self.hidden) { return [super pointInside:point withEvent:event]; } CGRect relativeFrame = self.bounds; CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.hitTestEdgeInsets); return CGRectContainsPoint(hitFrame, point); } @end