如何在UINavigationBar中编辑左,右UIBarButtonItem的空格[iOS 7]

Sal*_*idi 81 iphone uinavigationbar uibarbuttonitem ios ios7

我之前使用的是iOS 6.1,但现在我已经转移到iOS 7.除了其他问题之外,我观察到在我的导航栏中,左侧栏按钮项的左侧空间和右侧按钮栏项的右侧空白区域相当IOS 7比iOS 6更多.

我需要知道有没有办法可以减少导航栏中左,右栏按钮项的空格?

提前致谢.

Adn*_*tab 219

我也遇到了这个问题.我也有感觉在iOS 7中有更多的空间.而且我发现这大约多了10分.当我想要LeftBarItemButton从边缘开始时,我通常使用负空格.这对你也很有用.

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];
Run Code Online (Sandbox Code Playgroud)

  • 如果您执行[NSArray arrayWithObjects:requiredButton,negativeSpacer],它将不起作用.记住订单. (10认同)
  • 这似乎不适用于iOS 7. (5认同)
  • 它真的在iOS 7中工作,因为我现在在我的几个项目中使用它...点系统有所不同所以你必须照顾它.... (4认同)
  • 效果很好,请注意,对于rightBarButtonItems,如果要更改右边距,则spacer必须是数组中的第一项 (3认同)
  • @C_X 对于 iPhone 6,-16 的边距似乎不起作用。-20 似乎是正确的.. 知道我们如何在所有 iPhone 设备上正常工作吗? (2认同)
  • 不适用于 iOS 13!有谁知道如何在 iOS 13 中实现这一点? (2认同)

sme*_*mek 23

基于@C_X他的回答我创建了一个类别,它根据当前设备的iOS版本添加和定位UIBarButtonItem.

// 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
Run Code Online (Sandbox Code Playgroud)

在视图控制器中,您现在可以使用[self.navigationItem addLeftBarButtonItem:leftBarButtonItem];[self.navigationItem addRightBarButtonItem:rightBarButtonItem];

我也尝试了子类化UIButton和覆盖,-alignmentRectInsets但这给了我视图之间转换的问题.


Sim*_*mon 10

对于Swift 2.0,这是我获得以下效果的解决方案......

(实际值可能会有所不同,具体取决于您的具体情况)

在此输入图像描述

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)
Run Code Online (Sandbox Code Playgroud)

Swift 2.2更新:

对于Swift 2.2,该action: Selector方法已更改,应按以下方式键入

captureButton.addTarget(self, action: #selector(YourViewController.showCaptureDetailsForm(_:)), forControlEvents: .TouchUpInside)


jar*_*air 6

为了修复此错误,您必须进行子类化UIButton以便可以覆盖alignmentRectInsets.根据我的测试,你需要返回一个UIEdgeInsets正向右偏移或正向左偏移,具体取决于按钮位置.这些数字对我来说没有任何意义(根据常识,至少其中一个应该是负数),但这实际上是有效的:

- (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;
}
Run Code Online (Sandbox Code Playgroud)

特别感谢@zev建议我尝试调整alignmentRectInsets.


tua*_*pen 6

这是我的解决方案Swift 3.0

rightBtn.imageInsets = UIEdgeInsets(top: 0, left: -13.0, bottom: 0, right: 13.0) self.navigationItem.rightBarButtonItem = rightBtn
Run Code Online (Sandbox Code Playgroud)


Chr*_*ner 5

smek的带领下,我做了一个类别,但修改了它以提供向后兼容性而不是向前.我在iOS 7中设置了我想要的一切,然后如果用户运行的东西更低,我开始捣乱.

@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
Run Code Online (Sandbox Code Playgroud)

然后为了全局化,我有一个瘦的UIViewController子类,我的所有视图控制器都继承了它.

@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
Run Code Online (Sandbox Code Playgroud)

我意识到我正在检查OS版本两次(一次进入INFViewController和再次出现在类别中),我把它留在了类别中,我想在项目中的任何地方使用它作为一次性.


小智 5

对于swift你可以做到这一点

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 */]
Run Code Online (Sandbox Code Playgroud)


vin*_*nny 5

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
                }
            }
Run Code Online (Sandbox Code Playgroud)

  • 延迟调用此方法 (2认同)