Je rencontre un espacement/remplissage excessif UIBarButtonItem lors de l'utilisation des éléments LeftBarItems et RightBarItems (voir l'image ci-dessous). Les icônes utilisées sur les UIBarButtonItems ne contiennent pas de remplissage supplémentaire. Donc, j'aimerais savoir ce qui cause cela?
J'utilise ceci afin de supprimer de l'espace avant le premier élément.
Cependant, cela ne fonctionne pas entre les éléments système comme UIBarButtonSystemItemAdd
, uniquement avec UIBarButtonItem qui a 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 augmenté silencieusement les contraintes d'espacement horizontal pour UIBarButtonItems et, malheureusement, n'a toujours pas ajouté de méthode UIAppearance pour ajuster le positionnement horizontal de UIBarButtonItems.
La meilleure solution (qui a fonctionné pour moi) consiste à envelopper vos UIBarButtonItems dans une vue UIV à l’aide de initWithCustomView:
et à ajuster les limites de cette vue personnalisée pour obtenir le positionnement souhaité. Voici une bonne réponse sur la façon de faire cela .
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 bouton dans la barre de navigation dans iOS 7: le bouton avec image et le 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:(NSString*)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:(NSString*)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 pour bouton avec 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 Storybord.
1.Sélectionnez le Bar item
.
2.Sélectionnez le Size Inspector
.
Ici vous pouvez trouver une image insérée, en utilisant top
, bottom
ET left
, right
vous pouvez changer la position de l'élément de barre.
Comme @Luda commente, la solution consiste à
self.myBarButtonItem.imageInsets = UIEdgeInsetsMake(0, 25, 0, -25);
Cependant, @andrrs signale également un problème lorsque l'insert est grand: la zone touchée. Dans ce cas, nous devons implémenter un moyen de setHitTestEdgeInsets. Ci-dessous une méthode de catégorie:
@implementation UIButton (Extensions)
@dynamic hitTestEdgeInsets;
static const NSString *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