xcode 如何调整rightBarButtonItems中两个UIBarButtonItem之间的空间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22741824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to adjust space between two UIBarButtonItem in rightBarButtonItems
提问by Bob
I am using the following codes to add two button to self.navigationItem.rightBarButtonItems, and I think in iOS7, the space between two buttons are too wide, is there a way to decrease the space between these two buttons?
我正在使用以下代码向self.navigationItem.rightBarButtonItems添加两个按钮,我认为在iOS7中,两个按钮之间的空间太宽,有没有办法减少这两个按钮之间的空间?
UIBarButtonItem *saveStyleButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"save.png"] style:UIBarButtonItemStyleBordered target:self action:@selector(saveStyle)];
UIBarButtonItem *shareStyleButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(shareStyle)];
NSArray *arr= [[NSArray alloc] initWithObjects:shareStyleButton,saveStyleButton,nil];
self.navigationItem.rightBarButtonItems=arr;
Appreciate any hint or idea.
欣赏任何提示或想法。
回答by Bob
Updated at Jul 2015
2015 年 7 月更新
A better way to do this is to use storyboard (tested in Xcode 6.4). First, add a UINavigationItem; secondly, add a Bar Button Item; thirdly, add a view to the Bar Button Item you just created in step 2; fourthly, add as many buttons as you wish into that view you just dragged in; lastly, adjust the space with your mouse and constraints.
更好的方法是使用故事板(在 Xcode 6.4 中测试)。首先,添加一个UINavigationItem;其次,添加一个Bar Button Item;第三步,给你在第 2 步中创建的 Bar Button Item 添加一个视图;第四,在您刚刚拖入的视图中添加任意数量的按钮;最后,用鼠标和约束调整空间。
Related Questions
相关问题
Can't assign multiple Buttons to UINavigationItem when using Storyboard with iOS 5
在 iOS 5 中使用 Storyboard 时,无法将多个按钮分配给 UINavigationItem
How to add buttons to navigation controller visible after segueing?
Old Answer (Only acceptable for small insets)
旧答案(仅适用于小插图)
Use imageInsets property:
使用 imageInsets 属性:
leftButton.imageInsets = UIEdgeInsetsMake(0.0, 0.0, 0, -15);
rightButton.imageInsets = UIEdgeInsetsMake(0.0, -15, 0, 0);
for three or more buttons, the middle one(s) get both insets:
对于三个或更多按钮,中间的按钮会得到两个插图:
leftButton.imageInsets = UIEdgeInsetsMake(0.0, 0.0, 0, -15);
middleButton.imageInsets = UIEdgeInsetsMake(0.0, -15, 0, -15);
rightButton.imageInsets = UIEdgeInsetsMake(0.0, -15, 0, 0);
For the right side buttons, be careful: the FIRST button in the item array is the RIGHT one:
对于右侧按钮,请注意:项目数组中的第一个按钮是正确的:
rightButton.imageInsets = UIEdgeInsetsMake(0.0, -15, 0, 0);
middleButton.imageInsets = UIEdgeInsetsMake(0.0, -15, 0, -15);
leftButton.imageInsets = UIEdgeInsetsMake(0.0, 0.0, 0, -15);
IMPORTANT: Split the inset between the two neighbors; if apply the entire inset to one edge, it will become obvious that the buttons are overlapping in the "blank" space - one button gets all of the "gap" touches. Even when "split" the adjustment like this, at -40 on both edges, the tap will definitely go to wrong button sometimes. -15 or -20 is the most to consider using with this technique.
重要提示:在两个邻居之间拆分插图;如果将整个插图应用于一个边缘,很明显按钮在“空白”空间中重叠 - 一个按钮获得所有“间隙”触摸。即使像这样“拆分”调整,在两侧的 -40 处,水龙头有时肯定会转到错误的按钮。-15 或 -20 是最需要考虑使用这种技术的。
By applying this method, the button could even be moved around in four directions.
通过应用这种方法,按钮甚至可以在四个方向上移动。
回答by Ali Seymen
My solution is using a custom view for right bar buttons. Create a horizontal stackview with equal spacing and add any number of buttons as subview.
我的解决方案是为右栏按钮使用自定义视图。创建一个等间距的水平堆栈视图,并添加任意数量的按钮作为子视图。
Sample code:
示例代码:
func addRightBarButtonItems()
{
let btnSearch = UIButton.init(type: .custom)
btnSearch.setImage(UIImage(named: "icon-search"), for: .normal)
btnSearch.addTarget(self, action: #selector(MyPageContainerViewController.searchButtonPressed), for: .touchUpInside)
let btnEdit = UIButton.init(type: .custom)
btnEdit.setImage(UIImage(named: "icon-edit"), for: .normal)
btnEdit.addTarget(self, action: #selector(MyPageContainerViewController.editButtonPressed), for: .touchUpInside)
let stackview = UIStackView.init(arrangedSubviews: [btnEdit, btnSearch])
stackview.distribution = .equalSpacing
stackview.axis = .horizontal
stackview.alignment = .center
stackview.spacing = 8
let rightBarButton = UIBarButtonItem(customView: stackview)
self.navigationItem.rightBarButtonItem = rightBarButton
}
回答by ober
First:
第一的:
For UIBarButtonItem
you must use constructor init(customView: UIView)
因为UIBarButtonItem
你必须使用构造函数init(customView: UIView)
Second:
第二:
Use fixedSpace
for set space between buttons
使用fixedSpace
了按键之间设置空间
example:
例子:
let firstButton = UIButton()
let firstButtonItem = UIBarButtonItem(customView: firstButton)
let secondButton = UIButton()
let secondButtonItem = UIBarButtonItem(customView: secondButton)
let space = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
space.width = WIDTH
self.navigationItem.rightBarButtonItems = [firstButtonItem, space, secondButtonItem]
回答by abinop
If you are looking to have 2 buttons on the top right with no space in between them or on the right, this has worked for me.
如果您希望在右上角有 2 个按钮,它们之间或右侧没有空格,这对我有用。
let imgLeft = UIImage(named: "buttonLeft")?.imageWithRenderingMode(.AlwaysOriginal)
let bLeft = UIBarButtonItem(image: imgLeft, style: UIBarButtonItemStyle.Done, target: self, action: "action1:")
let space = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
space.width = -16.0
bLeft.imageInsets = UIEdgeInsetsMake(0, 0, 0, -25.0)
let imgRight = UIImage(named: "buttonRight")?.imageWithRenderingMode(.AlwaysOriginal)
let bRight = UIBarButtonItem(image: imgRight, style: UIBarButtonItemStyle.Done, target: self, action: "action2:")
bRight.imageInsets = UIEdgeInsetsMake(0, -25, 0, 0)
self.navigationItem.rightBarButtonItems = [space,bLeft,bRight ]
回答by A.G
My situation was about giving horizontal space to logOut Button to the right edge.
我的情况是在右侧边缘为 logOut Button 提供水平空间。
func addLogOutButtonToNavigationBar(triggerToMethodName: String)
{
let button: UIButton = UIButton()
button.setImage(UIImage(named: "logOff.png"), forState: .Normal)
button.frame = CGRectMake(20, 0, 30, 25)
button.contentEdgeInsets = UIEdgeInsets.init(top: 0, left: 10, bottom: 0, right: -10)
button .addTarget(self, action:Selector(triggerToMethodName), forControlEvents: UIControlEvents.TouchUpInside)
let rightItem:UIBarButtonItem = UIBarButtonItem()
rightItem.customView = button
self.navigationItem.rightBarButtonItem = rightItem
}
回答by sahilabrar
Might be a bit late for this answer however this can help the newest IOS+Swift combination (IOS 10 and Swift 3 in my case). Here I describe a general approach for how to move items right/left for rightBarButtonItems/leftBarButtonItems:
这个答案可能有点晚了,但这可以帮助最新的 IOS+Swift 组合(在我的例子中是 IOS 10 和 Swift 3)。在这里,我描述了如何为 rightBarButtonItems/leftBarButtonItems 向右/向左移动项目的一般方法:
The property you we have use here to move a barButtonItem is "imageEdgeInsets" . So, Here how to use this property -
我们在这里用来移动 barButtonItem 的属性是 "imageEdgeInsets" 。所以,这里如何使用这个属性 -
yourBarButtonItem.imageEdgeInsets = UIEdgeInsetsMake(top, left, bottom, right)
yourBarButtonItem.imageEdgeInsets = UIEdgeInsetsMake(top, left, bottom, right)
These top, left, bottom, right are of type CGFloat and these are basically margin value that pushes your item from/to each other. For decreasing a space, we can just use minus (-) values like this " -10 ".
这些顶部,左侧,底部,右侧是 CGFloat 类型,这些基本上是将您的项目推向/推向彼此的边距值。为了减少空格,我们可以只使用减号 (-) 值,例如“-10”。
So, for example if we want to use this for a group of leftBatButtonItems and say, if we want to move a item to the a bit right, then we can do this -
因此,例如,如果我们想将它用于一组 leftBatButtonItems 并说,如果我们想将一个项目向右移动一点,那么我们可以这样做 -
ourBarButtonItem.imageEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, -15)
I hope we get the general idea here and hope it helps :)
我希望我们在这里得到大致的想法并希望它有所帮助:)
回答by iOSCodeJunkie
Without any code. I just put another UIBarButtonItem in-between the buttons that need spacing in storyboard. The button is just a placeholder for spacing and the UIBarButton should have UIView as subview of the UIBarButtonItem. adjust the view's width for your spacing. See Screen shots.
无需任何代码。我只是在故事板中需要间距的按钮之间放置了另一个 UIBarButtonItem。该按钮只是用于间距的占位符,并且 UIBarButton 应该将 UIView 作为 UIBarButtonItem 的子视图。为您的间距调整视图的宽度。请参阅屏幕截图。
回答by Joride
Create a UIBarButtonItem
with type flexible or fixed space. Set the width and add it to the array of barbuttonitems. Try using a negative width, see if that works.
创建一个UIBarButtonItem
带有类型灵活或固定的空间。设置宽度并将其添加到 barbuttonitems 数组中。尝试使用负宽度,看看是否有效。
Or, you could maybe adjust your image. The system buttons i think have a fixed size, and might include some transparent part, so even when packed together the still seem spaced.
或者,您可以调整您的图像。我认为系统按钮的大小是固定的,并且可能包含一些透明部分,因此即使打包在一起,仍然看起来有间隔。
回答by Alex311
To accomplish this in code without adding an extra container view, use a UIBarButtonItem
with the system item type set to FixedSpace
. Then set the width of the fixed space to -10
and place it between the two buttons.
要在代码中完成此操作而不添加额外的容器视图,请使用UIBarButtonItem
系统项类型设置为 的FixedSpace
。然后将固定空间的宽度设置为-10
并放置在两个按钮之间。
回答by Jules
another answer : It works in ios 9 - 12. You should call fixNavigationItemsMargin(margin:)in function viewDidAppear(_ animated: Bool)and viewDidLayoutSubviews(). fixNavigationItemsMargin(margin:)would modify the UINavigationController stack.
另一个答案:它适用于 ios 9 - 12。您应该在函数 viewDidAppear( _animated : Bool)和viewDidLayoutSubviews() 中调用fixNavigationItemsMargin(margin:)。 fixNavigationItemsMargin(margin:)将修改 UINavigationController 堆栈。
you could call fixNavigationItemsMargin(margin:)in BaseNavigationController ,do the common work. And call fixNavigationItemsMargin(margin:)in UIViewController do precise layout.
你可以在 BaseNavigationController 中调用fixNavigationItemsMargin(margin:),做普通的工作。并在 UIViewController 中调用 fixNavigationItemsMargin(margin:)进行精确布局。
// do common initilizer
class BaseNavigationController: UINavigationController {
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
fixNavigationItemsMargin()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
fixNavigationItemsMargin()
}
}
extension UINavigationController {
func fixNavigationItemsMargin(_ margin: CGFloat = 8) {
let systemMajorVersion = ProcessInfo.processInfo.operatingSystemVersion.majorVersion
if systemMajorVersion >= 11 {
// iOS >= 11
guard let contentView = navigationBar.subviews
.first(
where: { sub in
String(describing: sub).contains("ContentView")
}) else { return }
// refer to: https://www.matrixprojects.net/p/uibarbuttonitem-ios11/
// if rightBarButtonItems has not any custom views, then margin would be 8(320|375)/12(414)
// should use customView
let needAdjustRightItems: Bool
if let currentVC = viewControllers.last,
let rightItems = currentVC.navigationItem.rightBarButtonItems,
rightItems.count > 0,
rightItems.filter({ ##代码##.customView != nil }).count > 0 {
needAdjustRightItems = true
} else {
print("Use 8(320|375)/12(414), if need precious margin ,use UIBarButtonItem(customView:)!!!")
needAdjustRightItems = false
}
let needAdjustLeftItems: Bool
if let currentVC = viewControllers.last,
let leftItems = currentVC.navigationItem.leftBarButtonItems,
leftItems.count > 0,
leftItems.filter({ ##代码##.customView != nil }).count > 0 {
needAdjustLeftItems = true
} else {
print("Use 8(320|375)/12(414), if need precious margin ,use UIBarButtonItem(customView:)!!!")
needAdjustLeftItems = false
}
let layoutMargins: UIEdgeInsets
if #available(iOS 11.0, *) {
let directionInsets = contentView.directionalLayoutMargins
layoutMargins = UIEdgeInsets(
top: directionInsets.top,
left: directionInsets.leading,
bottom: directionInsets.bottom,
right: directionInsets.trailing)
} else {
layoutMargins = contentView.layoutMargins
}
contentView.constraints.forEach(
{ cst in
// iOS 11 the distance between rightest item and NavigationBar should be margin
// rightStackView trailing space is -margin / 2
// rightestItem trailing to rightStackView trailing is -margin / 2
let rightConstant = -margin / 2
switch (cst.firstAttribute, cst.secondAttribute) {
case (.leading, .leading), (.trailing, .trailing):
if let stackView = cst.firstItem as? UIStackView,
stackView.frame.minX < navigationBar.frame.midX {
// is leftItems
if needAdjustLeftItems {
cst.constant = margin - layoutMargins.left
}
} else if let layoutGuide = cst.firstItem as? UILayoutGuide,
layoutGuide.layoutFrame.minX < navigationBar.frame.midX {
// is leftItems
if needAdjustLeftItems {
cst.constant = margin - layoutMargins.left
}
}
if let stackView = cst.firstItem as? UIStackView,
stackView.frame.maxX > navigationBar.frame.midX {
// is rightItems
if needAdjustRightItems {
cst.constant = rightConstant
}
} else if let layoutGuide = cst.firstItem as? UILayoutGuide,
layoutGuide.layoutFrame.maxX > navigationBar.frame.midX {
// is rightItems
if needAdjustRightItems {
cst.constant = rightConstant
}
}
default: break
}
})
// ensure items space == 8, minispcae
contentView.subviews.forEach(
{ subsub in
guard subsub is UIStackView else { return }
subsub.constraints.forEach(
{ cst in
guard cst.firstAttribute == .width
|| cst.secondAttribute == .width
else { return }
cst.constant = 0
})
})
} else {
// iOS < 11
let versionItemsCount: Int
if systemMajorVersion == 10 {
// iOS 10 navigationItem.rightBarButtonItems == 0
// space = 16(320|375) / 20(414)
// should adjust margin
versionItemsCount = 0
} else {
// iOS 9 navigationItem.rightBarButtonItems == 0
// space = 8(320|375) / 12(414)
// should not adjust margin
versionItemsCount = 1
}
let spaceProducer = { () -> UIBarButtonItem in
let spaceItem = UIBarButtonItem(
barButtonSystemItem: .fixedSpace,
target: nil,
action: nil)
spaceItem.width = margin - 16
return spaceItem
}
if let currentVC = viewControllers.last,
var rightItems = currentVC.navigationItem.rightBarButtonItems,
rightItems.count > versionItemsCount,
let first = rightItems.first {
// ensure the first BarButtonItem is NOT fixedSpace
if first.title == nil && first.image == nil && first.customView == nil {
print("rightBarButtonItems SPACE SETTED!!! SPACE: ", abs(first.width))
} else {
rightItems.insert(spaceProducer(), at: 0)
// arranged right -> left
currentVC.navigationItem.rightBarButtonItems = rightItems
}
}
if let currentVC = viewControllers.last,
var leftItems = currentVC.navigationItem.leftBarButtonItems,
leftItems.count > versionItemsCount,
let first = leftItems.first {
if first.title == nil && first.image == nil && first.customView == nil {
print("leftBarButtonItems SPACE SETTED!!! SPACE: ", abs(first.width))
} else {
leftItems.insert(spaceProducer(), at: 0)
// arranged left -> right
currentVC.navigationItem.leftBarButtonItems = leftItems
}
}
}
}
}
// do precise layout
class ViewController: UIViewController {
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
navigationController?.fixNavigationItemsMargin(40)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
navigationController?.fixNavigationItemsMargin(40)
}