在UINavigationBar中更改UIBarButtonItem的位置

如何更改UINavigationBar中UIBarButtonItem的位置? 我希望我的button比正常位置高出大约5px。

没有特别好的方法来做到这一点。 你最好的select是如果你真的必须inheritanceUINavigationBar,并重写layoutSubviews来调用[super layoutSubviews] ,然后find并重新定位button的视图。

此代码为图像背景和自定义位置创buildUINavigationBar的后退button。 诀窍是创build一个中间视图,并修改其边界。

 UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom]; UIImage *backBtnImage = [UIImage imageNamed:@"btn-back"]; UIImage *backBtnImagePressed = [UIImage imageNamed:@"btn-back-pressed"]; [backBtn setBackgroundImage:backBtnImage forState:UIControlStateNormal]; [backBtn setBackgroundImage:backBtnImagePressed forState:UIControlStateHighlighted]; [backBtn addTarget:self action:@selector(goBack) forControlEvents:UIControlEventTouchUpInside]; backBtn.frame = CGRectMake(0, 0, 63, 33); UIView *backButtonView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 63, 33)]; backButtonView.bounds = CGRectOffset(backButtonView.bounds, -14, -7); [backButtonView addSubview:backBtn]; UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:backButtonView]; self.navigationItem.leftBarButtonItem = backButton; 

我解决了使用转换和自定义视图:

(迅速)

  // create the button let suggestImage = UIImage(named: "tab-item-popcorn-on")!.imageWithRenderingMode(.AlwaysOriginal) let suggestButton = UIButton(frame: CGRectMake(0, 0, 40, 40)) suggestButton.setBackgroundImage(suggestImage, forState: .Normal) suggestButton.addTarget(self, action: Selector("suggesMovie:"), forControlEvents:.TouchUpInside) // here where the magic happens, you can shift it where you like suggestButton.transform = CGAffineTransformMakeTranslation(10, 0) // add the button to a container, otherwise the transform will be ignored let suggestButtonContainer = UIView(frame: suggestButton.frame) suggestButtonContainer.addSubview(suggestButton) let suggestButtonItem = UIBarButtonItem(customView: suggestButtonContainer) // add button shift to the side navigationItem.rightBarButtonItem = suggestButtonItem 

对于那些正在为iOS 5开发的人,偶然发现了这一点,并感到气馁…试试这样:

 float my_offset_plus_or_minus = 3.0f; UIBarButtonItem * item = [[UIBarButtonItem alloc] initWithTitle:@"title" style:UIBarButtonItemStyleDone target:someObject action:@selector(someMessage)]; [item setBackgroundVerticalPositionAdjustment:my_offset_plus_or_minus forBarMetrics:UIBarMetricsDefault]; 

最好的方法是inheritance你的UINavigationBar,如下所述: https : //stackoverflow.com/a/17434530/1351190

这是我的例子:

 #define NAVIGATION_BTN_MARGIN 5 @implementation NewNavigationBar - (void)layoutSubviews { [super layoutSubviews]; UINavigationItem *navigationItem = [self topItem]; UIView *subview = [[navigationItem rightBarButtonItem] customView]; if (subview) { CGRect subviewFrame = subview.frame; subviewFrame.origin.x = self.frame.size.width - subview.frame.size.width - NAVIGATION_BTN_MARGIN; subviewFrame.origin.y = (self.frame.size.height - subview.frame.size.height) / 2; [subview setFrame:subviewFrame]; } subview = [[navigationItem leftBarButtonItem] customView]; if (subview) { CGRect subviewFrame = subview.frame; subviewFrame.origin.x = NAVIGATION_BTN_MARGIN; subviewFrame.origin.y = (self.frame.size.height - subview.frame.size.height) / 2; [subview setFrame:subviewFrame]; } } @end 

希望它有帮助。

尝试下面的代码,

 UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithTitle:@"Logout" style:UIBarButtonItemStyleDone target:self action:nil]; [button setBackgroundVerticalPositionAdjustment:-20.0f forBarMetrics:UIBarMetricsDefault]; [[self navigationItem] setRightBarButtonItem:button]; 

它用来在这个代码中改变'y'的位置。 根据您的要求更改'y'值(这里是-20.0f)。 如果该值为正值,则会按下button位置。 如果该值为负值,则会调高button位置。

我需要把我的button设置得更靠右。 下面是我在Swift中使用UIAppearance的方法。 还有一个垂直位置的属性,所以我想你可以在任何方向调整。

 UIBarButtonItem.appearance().setTitlePositionAdjustment(UIOffset.init(horizontal: 15, vertical: 0), forBarMetrics: UIBarMetrics.Default) 

对我来说,这比直接搞乱框架或者添加自定义的子视图要容易得多。

如果您只是使用图像而不是默认的镶边,则可以使用负像插图(在尺寸检查器中设置)在UIBarButtonItem中移动图像(方便,因为默认情况下,水平填充会导致图像进一步到你想要的内部)。 您可以使用图像插入来将图像定位在UIBarButtonItem的边界之外,并且左侧button的整个附近都是可以放置的,所以您不必担心确保它位于靠近点击目标。 (至less在合理的范围内)

Swift 3.1

 let cancelBarButtonItem = UIBarButtonItem() cancelBarButtonItem.setBackgroundVerticalPositionAdjustment(4, for: .default) vc.navigationItem.setLeftBarButton(cancelBarButtonItem, animated: true) 
  • Swift 3
  • 自定义导航栏高度
  • 没有标题跳跃

步骤1:使用Appearance API设置标题位置。 例如,在AppDelegate的didFinishLaunchingWithOptions中

 UINavigationBar.appearance().setTitleVerticalPositionAdjustment(-7, for: .default) 

第2步:子类UINavigationBar

 class YourNavigationBar: UINavigationBar { let YOUR_NAV_BAR_HEIGHT = 60 override func sizeThatFits(_ size: CGSize) -> CGSize { return CGSize(width: UIScreen.main.bounds.width, height: YOUR_NAV_BAR_HEIGHT) } override func layoutSubviews() { super.layoutSubviews() let navigationItem = self.topItem for subview in subviews { if subview == navigationItem?.leftBarButtonItem?.customView || subview == navigationItem?.rightBarButtonItem?.customView { subview.center = CGPoint(x: subview.center.x, y: YOUR_NAV_BAR_HEIGHT / 2) } } } } 

我能find的最佳解决scheme是使用子视图来初始化一个UIBarButtonItem,该子视图包含左侧/右侧的额外空间。 这样你就不必担心子类化,并改变导航栏内其他元素的布局,比如标题。

例如,要将一个button14指向左侧:

 UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, image.size.width + 14, image.size.height)]; UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(-14, 0, image.size.width, image.size.height); [button setImage:image forState:UIControlStateNormal]; [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; [containerView addSubview:button]; UIButton* button2 = [UIButton buttonWithType:UIButtonTypeCustom]; button2.frame = CGRectMake(0, 0, image.size.width + 14, image.size.height); [button2 addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; [containerView addSubview:button2]; UIBarButtonItem* item = [[[self alloc] initWithCustomView:containerView] autorelease]; 

正如@Anomie所说,我们需要inheritanceUINavigationBar并重写layoutSubviews()

这会将所有右键菜单项牢固地连接到导航栏的右侧(而不是默认情况下稍微左alignment)

 class AdjustedNavigationBar: UINavigationBar { override func layoutSubviews() { super.layoutSubviews() if let rightItems = topItem?.rightBarButtonItems where rightItems.count > 1 { for i in 0..<rightItems.count { let barButtonItem = rightItems[i] if let customView = barButtonItem.customView { let frame = customView.frame customView.frame = CGRect(x: UIApplication.sharedApplication().windows.last!.bounds.size.width-CGFloat(i+1)*44, y: frame.origin.y, width: frame.size.width, height: frame.size.height) } } } } } 

唯一可以设置UINavigationController的UINavigationBar属性的地方在init()中,如下所示:

 let controllerVC = UINavigationController(navigationBarClass: AdjustedNavigationBar.self, toolbarClass: nil) controllerVC.viewControllers = [UIViewController()] 

第二行设置UINavigationController的根视图控制器(因为我们不能通过init(rootViewController:)来设置它

在自定义视图中使用自定义视图和重载UIBarButtonItem来初始化UIBarButtonItem ,就像这样

 -(void) layoutSubviews { [super layoutSubviews]; CGRect frame = self.frame; CGFloat offsetY = 5; frame.origin.y = (44 - frame.size.height) / 2 - offsetY; self.frame = frame; } 

这里是Adriano使用Swift 3的解决scheme。这是唯一的解决scheme,为我工作,我尝试了几个。

  let suggestImage = UIImage(named: "menu.png")! let suggestButton = UIButton(frame: CGRect(x:0, y:0, width:34, height:20)) suggestButton.setBackgroundImage(suggestImage, for: .normal) suggestButton.addTarget(self, action: #selector(self.showPopover(sender:)), for:.touchUpInside) suggestButton.transform = CGAffineTransform(translationX: 0, y: -8) // add the button to a container, otherwise the transform will be ignored let suggestButtonContainer = UIView(frame: suggestButton.frame) suggestButtonContainer.addSubview(suggestButton) let suggestButtonItem = UIBarButtonItem(customView: suggestButtonContainer) // add button shift to the side navigationItem.leftBarButtonItem = suggestButtonItem 

这是一个简单的解决方法,足以满足我的需求。 我在UINavigationBar的右侧添加了一个信息button,但是默认情况下它靠的太靠近边缘。 通过延长框架的宽度,我可以创build右侧所需的额外间距。

  UIButton *info = [UIButton buttonWithType:UIButtonTypeInfoLight]; CGRect frame = info.frame; frame.size.width += 20; info.frame = frame; myNavigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]initWithCustomView:info]autorelease]; 

您始终可以使用button上的“插入”进行调整。 例如,

 UIButton *toggleBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [toggleBtn setFrame:CGRectMake(0, 0, 20, 20)]; [toggleBtn addTarget:self action:@selector(toggleView) forControlEvents:UIControlEventTouchUpInside]; [toggleBtn setImageEdgeInsets:((IS_IPAD)? UIEdgeInsetsMake(0,-18, 0, 6) : UIEdgeInsetsMake(0, -3, 0, -3))]; UIBarButtonItem *toggleBtnItem = [[UIBarButtonItem alloc] initWithCustomView: toggleBtn]; self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:searchBtnItem, toggleBtnItem, nil]; 

它适用于我。

通过在自定义button的图像边缘插入中进行调整,我发现了这个问题的解决scheme。 我有在应用程序的要求,以增加导航栏的高度,并增加高度后,使rightBarButtonItem和leftBarButtonItem图像未定位的问题。

find下面的代码: –

 UIImage *image = [[UIImage imageNamed:@"searchbar.png"]; UIButton* searchbutton = [UIButton buttonWithType:UIButtonTypeCustom]; [searchbutton addTarget:self action:@selector(searchBar:) forControlEvents:UIControlEventTouchUpInside]; searchbutton.frame = CGRectMake(0,0,22, 22); [searchbutton setImage:image forState:UIControlStateNormal]; [searchbutton setImageEdgeInsets:UIEdgeInsetsMake(-50, 0,50, 0)]; // Make BarButton Item UIBarButtonItem *navItem = [[UIBarButtonItem alloc] initWithCustomView:searchbutton]; self.navigationItem.rightBarButtonItem = navItem; 

希望这有助于任何人。