在UINavigationBar中更改UIBarButtonItem的宽度

25

我正在创建一个UIBarButtonItem并将其添加到我的导航栏中:

(void)viewDidLoad { 

   ...

   // Add the refresh button to the navigation bar
   UIButton *refreshButton = [UIButton buttonWithType:UIButtonTypeCustom];
   [refreshButton setFrame:CGRectMake(0,0,30,30)];
   [refreshButton setImage:[UIImage imageNamed:@"G_refresh_icon.png"] forState:UIControlStateNormal];
   [refreshButton addTarget:self action:@selector(refreshData) forControlEvents:UIControlEventTouchUpInside];
   UIBarButtonItem *refreshBarButton = [[[UIBarButtonItem alloc] initWithCustomView:refreshButton] autorelease];
   self.navigationItem.leftBarButtonItem = refreshBarButton;
}

代码运行时看起来没问题,但我可以在导航栏上任意位置点击并选择条形按钮,而不仅仅是在 x = 0 到大约100 的区域内。如何调整可选择的区域宽度为30像素?


2
很抱歉,我认为没有办法调整可选择区域。不过我有一个问题,为什么您想要宽度为30像素?iOS人机界面指南规定,可点击的UI元素的舒适最小尺寸为44 x 44点。 http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/MobileHIG/Characteristics/Characteristics.html - Sani
嗯,好的,谢谢你提供指南的链接。不过可选择区域这么宽有点奇怪。 - Darren
@AbdSaniAbdJalal,我们能否在Storyboard中更改barbuttonitem的宽度? - aircraft
6个回答

35

自从iOS 11开始,仅为customView设置框架而不是UIBarButtonItem将无法正常工作(如被接受的答案中所建议的)。似乎向UIBarButtonItem添加Autolayout会覆盖设置框架的操作。 这篇帖子给了我灵感:

navigationItem.leftBarButtonItem?.customView = yourCustomButtonView
let desiredWidth = 35.0
let desiredHeight = 35.0

let widthConstraint = NSLayoutConstraint(item: yourCustomButtonView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: desiredWidth)
let heightConstraint = NSLayoutConstraint(item: yourCustomButtonView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: desiredHeight)

yourCustomButtonView.addConstraints([widthConstraint, heightConstraint])

需要注意的是,最好使用UIButton作为您的CustomView,因为您必须依赖它来触发操作。


很惊讶地发现导航栏默认使用自动布局来放置其中的项目,这里有非常有用的信息。 - noobular
谢谢!重要的是要知道,操纵帧将不再起作用。 - Hendrik

13

你可以考虑使用 initWithCustomView: 方法创建一个 UIBarButtonItem。这种方法并不理想,因为你不能直接得到“选中”状态,同时如果你想要这样的外观,你还需要将边框背景与按钮图像合成,但是这种方法可以更直接地指定工具栏项的框架。如果你使用文本而不是图像作为标题,仍然需要添加一个背景图像作为子视图。无论如何,我现在也遇到了同样的问题,这段代码对我有用:

UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"button-image.png"]];
imageView.frame = CGRectMake(0, 0, 43, 30);

UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:imageView];

self.navigationItem.leftBarButtonItem = barButtonItem;

目前这是我所知道的限制向UINavigationControllernavigationItem添加UIBarButtonItem自动调整大小的唯一方法。

或者尝试Maggie的解决方案,比我的更全面


2
只有当我使用 UIButton 作为自定义视图时才有效,而不是 UIImageView - Kreutzer
2
这个解决方案行不通,因为它根本没有按钮操作。请使用 UIButton 替代。 - Raptor

8
重要的是要意识到,您正在更改自定义视图的宽度,而不是UIBarButton本身。
因此代码如下:
CGRect resizedFrame = myBarButtonItem.customView.frame;
resizedFrame.size.width = myNewWidth;
myBarButtonItem.customView.frame = resizedFrame;

您还需要触发布局更改:
[myNavigationBar setNeedsLayout];

所有这些都表明布局是使用自动调整大小和框架完成的。尝试使用自动布局进行导航栏操作未能成功。请参阅我的问题Auto Layout with UINavigationBar and UIBarButtonItem
抱歉,我刚意识到我的代码几乎与@oscartzombie相同。这不是故意的!我会保留此答案,因为我认为它值得添加布局和其他要点,以及不涉及界面生成器或图像的解释。

我在使用自定义UIBarButtonItem的大小时遇到了问题,解决方法是在我的视图控制器的-(void)viewDidLoad方法中调用[self.navigationController.navigationBar setNeedsLayout]; - LunaCodeGirl
1
非常被低估的答案,解决了我的问题,谢谢@MaxMacLeod - Reinier Melian

6

您可以通过从界面构建器将图像拖到条形按钮项并使用以下代码更改自定义视图的宽度来完成此操作:

CGRect frame = self.navigationItem.leftBarButtonItem.customView.frame;
frame.size.width = 141;
self.navigationItem.leftBarButtonItem.customView.frame = frame;

当我在界面构建器中设置一个条形按钮项的图像属性时,我的自定义视图是空的。 - ndreisg

6

对于我来说,这些解决方案都没有起作用,而且我发现自动调整大小会覆盖你在代码中编写的尺寸。

通过 UIButton 方式创建按钮后,编写以下代码块:

[self.navigationItem.rightBarButtonItem.customView.widthAnchor constraintEqualToConstant:mWidth].active = YES;
[self.navigationItem.rightBarButtonItem.customView.heightAnchor constraintEqualToConstant:mHeight].active = YES;

5
以下方法可行,查看代码以更改按钮的宽度和高度,并添加操作项。
UIButton *imageButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 22, 22)];
[imageButton setBackgroundImage:[UIImage imageNamed:@"message_button"] forState:UIControlStateNormal];
[imageButton addTarget:self action:@selector(messageButtonTapped) forControlEvents:UIControlEventAllEvents];
UIBarButtonItem *leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:imageButton];
self.navigationItem.leftBarButtonItem = leftBarButtonItem;

注意:UIBarButtonItem的目标和操作不适用于图像视图。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接