24

我正在创建一个 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 像素的宽度?

4

6 回答 6

30

从 iOS 11 开始,仅设置框架customViewUIBarButtonItem不是不起作用(如接受的答案中建议的那样)。似乎添加 Autolayout 以UIBarButtonItem覆盖设置的框架。 这篇文章给了我这个想法:

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,因为您必须依靠它来触发操作。

于 2018-04-05T15:13:54.697 回答
13

UIBarButtonItem您可能会考虑的一种方法是通过调用创建一个initWithCustomView:. 这并不理想,因为您没有开箱即用的“选定”状态,并且您必须将带边框的背景(如果想要那种外观)与您的按钮图像合成,但是您可以更直接地为您的工具栏项。如果您使用文本作为标题而不是图像,您可能仍需要添加背景图像作为子视图。无论如何,我现在遇到了同样的问题,这段代码对我有用:

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;

现在这是我所知道的限制UIBarButtonItem添加到 s 的 sUINavigationController的自动调整大小的唯一方法navigationItem

或者试试 Maggie 的解决方案,它比我的更彻底

于 2012-12-03T22:36:58.863 回答
7

关键是要意识到您正在更改自定义视图的宽度,而不是其UIBarButton本身。

因此代码是:

CGRect resizedFrame = myBarButtonItem.customView.frame;
resizedFrame.size.width = myNewWidth;
myBarButtonItem.customView.frame = resizedFrame;

您还需要触发布局更改:

[myNavigationBar setNeedsLayout];

所有这一切都不言而喻,布局是通过自动调整大小和框架完成的。使用自动布局侵入导航栏没有成功。请参阅我的问题Auto Layout with UINavigationBar 和 UIBarButtonItem

抱歉刚刚意识到我的代码与@oscartzombie 几乎相同。不是故意的!我会留下这个答案,因为我认为值得添加布局和其他点,除了在不参考 Interface Bulder 或图像的情况下进行解释。

于 2013-07-19T13:06:10.280 回答
6

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

CGRect frame = self.navigationItem.leftBarButtonItem.customView.frame;
frame.size.width = 141;
self.navigationItem.leftBarButtonItem.customView.frame = frame;
于 2013-01-11T15:27:06.070 回答
6

这些解决方案都不适合我,我发现自动调整大小会覆盖您在代码中编写的尺寸。

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

[self.navigationItem.rightBarButtonItem.customView.widthAnchor constraintEqualToConstant:mWidth].active = YES;
[self.navigationItem.rightBarButtonItem.customView.heightAnchor constraintEqualToConstant:mHeight].active = YES;
于 2018-11-13T12:16:03.973 回答
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 的目标和动作不适用于图像视图

于 2015-05-27T09:57:06.957 回答