UIBarButtonItem在iOS 11的导航栏中为空格

在iOS 10及更低版本中,有一种方法可以在导航栏中的button数组中添加一个负间距,如下所示:

UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; negativeSpacer.width = -8; self.navigationItem.leftBarButtonItems = @[negativeSpacer, [self backButtonItem]]; 

这不再适用于iOS 11(间隔变为正值,而不是负值)。 我已经检查了栏button项的视图层次结构,现在它embedded到_UIButtonBarStackView 。 如何调整iOS 11上的酒吧button的位置?

我在苹果开发者论坛上发现了一个有点冒险的解决scheme: https : //forums.developer.apple.com/thread/80075

看起来问题来自iOS 11如何处理UIBarButtonItem .fixedSpacebutton以及如何在iOS 11中布置UINavigationBar 。导航栏现在使用自动布局和布局边距来布置button。 该post(底部)中提出的解决scheme是将所有布局页边距设置为您想要的某个值。

 class InsetButtonsNavigationBar: UINavigationBar { override func layoutSubviews() { super.layoutSubviews() for view in subviews { // Setting the layout margins to 0 lines the bar buttons items up at // the edges of the screen. You can set this to any number to change // the spacing. view.layoutMargins = .zero } } } 

要使用自定义button间距的新导航栏,您需要使用以下代码更新您创build任何导航控制器的位置:

 let navController = UINavigationController(navigationBarClass: InsetButtonsNavigationBar.self, toolbarClass: UIToolbar.self) navController.viewControllers = [yourRootViewController] 

基于keithbhunter的答案,我创build了一个自定义的UINavigationBar:

NavigationBarCustomMargins.h:

 #import <UIKit/UIKit.h> @interface NavigationBarCustomMargins : UINavigationBar @property (nonatomic) IBInspectable CGFloat leftMargin; @property (nonatomic) IBInspectable CGFloat rightMargin; @end 

NavigationBarCustomMargins.m:

 #import "NavigationBarCustomMargins.h" #define DefaultMargin 16 #define NegativeSpacerTag 87236223 @interface NavigationBarCustomMargins () @property (nonatomic) BOOL leftMarginIsSet; @property (nonatomic) BOOL rightMarginIsSet; @end @implementation NavigationBarCustomMargins @synthesize leftMargin = _leftMargin; @synthesize rightMargin = _rightMargin; - (void)layoutSubviews { [super layoutSubviews]; if (([[[UIDevice currentDevice] systemVersion] compare:@"11.0" options:NSNumericSearch] != NSOrderedAscending)) { BOOL isRTL = [UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft; for (UIView *view in self.subviews) { view.layoutMargins = UIEdgeInsetsMake(0, isRTL ? self.rightMargin : self.leftMargin, 0, isRTL ? self.leftMargin : self.rightMargin); } } else { //left NSMutableArray *leftItems = [self.topItem.leftBarButtonItems mutableCopy]; if (((UIBarButtonItem *)leftItems.firstObject).tag != NegativeSpacerTag) { UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; negativeSpacer.tag = NegativeSpacerTag; negativeSpacer.width = self.leftMargin - DefaultMargin; [leftItems insertObject:negativeSpacer atIndex:0]; [self.topItem setLeftBarButtonItems:[leftItems copy] animated:NO]; } //right NSMutableArray *rightItems = [self.topItem.rightBarButtonItems mutableCopy]; if (((UIBarButtonItem *)rightItems.firstObject).tag != NegativeSpacerTag) { UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; negativeSpacer.tag = NegativeSpacerTag; negativeSpacer.width = self.rightMargin - DefaultMargin; [rightItems insertObject:negativeSpacer atIndex:0]; [self.topItem setRightBarButtonItems:[rightItems copy] animated:NO]; } } } - (CGFloat)leftMargin { if (_leftMarginIsSet) { return _leftMargin; } return DefaultMargin; } - (CGFloat)rightMargin { if (_rightMarginIsSet) { return _rightMargin; } return DefaultMargin; } - (void)setLeftMargin:(CGFloat)leftMargin { _leftMargin = leftMargin; _leftMarginIsSet = YES; } - (void)setRightMargin:(CGFloat)rightMargin { _rightMargin = rightMargin; _rightMarginIsSet = YES; } @end 

之后,我在界面生成器中将自定义类设置为我的UINavigationController,并设置需要的边距: 截图1

工作正常。 支持RTL和iOS之前的11: 截图2

只是我的情况的解决方法,这可能对一些人有所帮助。 我想实现这一点:

在这里输入图像说明 之前我也在使用negativeSpacer。 现在我想出了这个解决scheme:

  let logoImage = UIImage(named: "your_image") let logoImageView = UIImageView(image: logoImage) logoImageView.frame = CGRect(x: -16, y: 0, width: 150, height: 44) logoImageView.contentMode = .scaleAspectFit let logoView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 44)) **logoView.clipsToBounds = false** logoView.addSubview(logoImageView) let logoItem = UIBarButtonItem(customView: logoView) navigationItem.leftBarButtonItem = logoItem 

对于我这个答案帮助https://stackoverflow.com/a/44896832
特别是我已经设置了imageEdgeInsetstitleEdgeInsets,因为我的button有图像和标题在一起