【问题标题】:How to Edit Empty Spaces of Left, Right UIBarButtonItem in UINavigationBar [iOS 7]如何在 UINavigationBar [iOS 7] 中编辑左、右 UIBarButtonItem 的空白
【发布时间】:2013-09-25 17:25:49
【问题描述】:

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

我想知道有没有办法可以减少导航栏中左右栏按钮项的空白??

提前致谢。

【问题讨论】:

标签: ios iphone ios7 uinavigationbar uibarbuttonitem


【解决方案1】:

这是我对Swift 3.0 的解决方案:

rightBtn.imageInsets = UIEdgeInsets(top: 0, left: -13.0, bottom: 0, right: 13.0) 
self.navigationItem.rightBarButtonItem = rightBtn

【讨论】:

    【解决方案2】:

    为我工作

    rightBarButton.customView?.transform = CGAffineTransform(translationX: 10, y: 0)

    【讨论】:

      【解决方案3】:

      负空间不适用于 iOS 11

      override func viewWillLayoutSubviews() {
          super.viewWillLayoutSubviews()
          // to remove navigation bar extra margin
          for view in (self.navigationController?.navigationBar.subviews)! {
              view.layoutMargins = UIEdgeInsets.zero
          }
      }
      

      上面的代码将从leftBarButtonItem 和RightBarButtonItem 两侧删除边距。如果您需要添加额外的边距(删除边距后)添加以下代码

          let rightButton = UIButton(frame: CGRect(x: 0, y: 0, width: 17, height: 20))
          rightButton.setImage(UIImage(named: "ic_cart"), for: .normal)
      
          let rightBarButtomItem = UIBarButtonItem(customView: rightButton)
      
          let spacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: nil, action: nil)
          spacer.width = 28 //This will add extra margin on right side
          navigationItem.rightBarButtonItems = [spacer,rightBarButtomItem]
      

      【讨论】:

      • '客户端尝试更改私有视图的布局边距时出错'
      【解决方案4】:

      我也遇到过这个问题。我也觉得在 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];
      

      【讨论】:

      • 它在 iOS 7 中确实有效,因为我现在在我的几个项目中使用它......积分系统有所不同,所以你必须照顾它......跨度>
      • 如果你这样做 [NSArray arrayWithObjects:requiredButton,negativeSpacer] 将不起作用。注意顺序。
      • 效果很好,请注意,对于 rightBarButtonItems,如果要更改右边距,则分隔符必须是数组中的第一项
      • @C_X 对于 iPhone 6,-16 边距似乎不起作用。 -20 似乎是正确的.. 知道如何才能在所有 iPhone 设备上正常工作吗?
      • 不适用于 iOS 13!有谁知道如何在 iOS 13 中实现这一点?
      【解决方案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
                      }
                  }
      

      【讨论】:

      • 这个方法调用延迟
      • 这是执行此操作的准确解决方案,负空间在 iOS 11 中无法使用
      【解决方案6】:

      斯威夫特 3.1

      给左栏按钮项目负空间:

          let backButton = UIButton.init(type: .custom)
          backButton.frame = CGRect.init(x: 0, y: 0, width: 40, height: 40)
          // negative space
          backButton.contentEdgeInsets = UIEdgeInsets(top: 0, left: -44.0, bottom: 0, right: 0)
          backButton.setImage(Ionicons.iosArrowBack.image(30, color: UIColor(hex: 0xFD6250)), for: .normal)
          backButton.addTarget(self, action: #selector(InviteVC.goBack), for: .touchUpInside)   
          // set back button
          self.navigationItem.leftBarButtonIteUIBarButtonItem.init(customView: backButton) 
      

      【讨论】:

        【解决方案7】:

        斯威夫特 3:

        let negativeSpacer:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil)
                negativeSpacer.width = -10
        self.navigationItem.leftBarButtonItems = [negativeSpacer, yourBarButtonItem]
        

        【讨论】:

          【解决方案8】:

          对于 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)
          

          Swift 2.2 更新:

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

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

          【讨论】:

            【解决方案9】:

            你可以这样做

            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 */]
            

            【讨论】:

              【解决方案10】:

              为了修复这个错误,你必须继承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;
              }
              

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

              【讨论】:

              • 感谢您的回答。虽然这是一个很好的解决方案,但我更喜欢@C_X 答案,因为现在我正试图避免子类化..
              • 这导致我在 iOS 6 中的动画期间按钮发生了一些奇怪的移动,它们会从错误的位置开始并在动画完成后移动以匹配插图。
              • 我不会感到惊讶。上面的代码只需要为 iOS 7 构建一个 iOS 6 风格的布局。
              • 快速修复,干得好。但是对于 iOS 9,您需要返回未设置的插图:
              【解决方案11】:

              不错的决定,非常感谢! 我只需要在导航标题的左侧添加两个元素。 这是我的解决方案:

                // Settings Button
                // This trick correct spacing between two left buttons
                UIBarButtonItem *settingsButtonItem = [[UIBarButtonItem alloc] init];
                UIView *settingsButtonItemView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 22.0, 22.0)];
                settingsButtonItem.customView = settingsButtonItemView;
                UIButton *settingsButton = [UIButton buttonWithType:UIButtonTypeSystem];
                settingsButton.frame = settingsButtonItemView.frame;
                [settingsButton setImage:[UIImage imageNamed:@"settings"] forState:UIControlStateNormal];
                settingsButton.tintColor = [[[[UIApplication sharedApplication] delegate] window] tintColor];
                [settingsButton addTarget:self action:@selector(showSettings:) forControlEvents:UIControlEventTouchDown];
                [settingsButtonItemView addSubview:settingsButton];
              
                // Star Button
                UIBarButtonItem *starButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"star_gray"] style:UIBarButtonItemStyleBordered target:self action:@selector(showStarred)];
                starButtonItem.width = 22.0;
                NSLog(@"%f", starButtonItem.width);
              
                // Negative Spacer
                // It shifts star button to the left
                UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
                negativeSpacer.width = -10.0;
              
                NSArray *leftNavigtaionBarButtonItems = @[negativeSpacer, starButtonItem, settingsButtonItem];
                [self.navigationItem setLeftBarButtonItems:leftNavigtaionBarButtonItems];
              

              【讨论】:

                【解决方案12】:

                smek's lead 之后,我创建了一个类别,但对其进行了修改以提供向后兼容性而不是向前兼容性。我在 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
                

                然后为了在全局范围内获得它,我有一个薄的 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
                

                我意识到我正在检查操作系统版本两次(一次在 INFViewController 中,然后在类别中),我将其留在类别中,以防我想在项目中的任何地方一次性使用它。

                【讨论】:

                  【解决方案13】:

                  根据@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
                  

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

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

                  【讨论】:

                    【解决方案14】:

                    我相信您需要使用带有UIButton 子类的自定义按钮,并在您的子类中覆盖-alignmentRectInsets。我忘记了适当的边缘是否需要正值或负值才能使其正确移动,但如果一个不起作用,请尝试另一个。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多