iOS7的导航栏button过度填充

我使用LeftBarItems和RightBarItems时遇到了过多的UIBarButtonItem填充/间距(请参阅下图)。 UIBarButtonItems上使用的图标不包含额外的填充。 所以我想知道是什么原因造成的?

在这里输入图像说明

我使用这个为了删除第一个项目之前的空间。

但是它不能在UIBarButtonSystemItemAdd类的系统项目之间工作,只能在具有图像的UIBarButtonItem中使用。

 @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 

像这样使用它:


 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]; 

您可以移动图像

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

苹果默默地增加了UIBarButtonItems的水平间距约束,可悲的是,仍然没有添加任何UIAppearance方法来调整UIBarButtonItems的水平位置。

最好的解决scheme(为我工作)是使用initWithCustomView:将UIBarButtonItems包装在UIView中initWithCustomView:并调整该自定义视图的边界以获得所需的位置。 这是如何做到这一点的一个很好的答案 。

如果您想进一步了解,可以使用类方法在UIBarButtonItem上创build一个类别,以返回您在应用程序中使用的栏button。 这样,当你需要一个酒吧button,你可以打电话像这样:

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

iOS 7中的导航栏上有两种button:带图像的button和带文本的button。 我写了一个class去做。 这里是如何:

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:

带图像的button示例:

 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; 

带文本的button示例:

 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:)]; 

而已。

我通过使用storybord接口解决了这个问题。

1.selectBar item

2.selectSize Inspector

在这里你可以find图像插入,使用topbottomleftright你可以改变酒吧项目的位置。

正如@Luda所言,解决的办法是

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

然而@andrrs在embedded很大的时候也指出了一个问题:命中区域。 在这种情况下,我们必须实现一种设置HitTestEdgeInsets的方法。 以下是一个分类方法:

 @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