2010-05-09 80 views
61

我有一个UIBarButtonItem的自定义视图,通过调用-initWithCustomView进行设置。 我的酒吧按钮项呈现很好,但是当我点击它时,它不会调用我的目标对象上的动作。UIBarButtonItem:目标操作不起作用?

这里是我的代码:

UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"someImage.png"]]; 
UIBarButtonItem *bbItem = [[UIBarButtonItem alloc] initWithCustomView:imageView]; 
self.navigationItem.leftBarButtonItem = bbItem; 
[imageView release]; 
[bbItem setTarget:self]; 
[bbItem setAction:@selector(deselectAll)]; 

回答

103

我不认为UIBarButtonItem的目标和动作适用于自定义视图。尝试使用UIButton而不是UIImageView并将目标和操作应用于按钮。在斯威夫特

示例代码:

let button = UIButton(type: .Custom) 
if let image = UIImage(named:"icon-menu.png") { 
    button.setImage(image, forState: .Normal) 
} 
button.frame = CGRectMake(0.0, 0.0, 30.0, 30.0) 
button.addTarget(self, action: #selector(MyClass.myMethod), forControlEvents: .TouchUpInside) 
let barButton = UIBarButtonItem(customView: button) 
navigationItem.leftBarButtonItem = barButton 
+0

@drawnonward,非常感谢! – 2010-05-09 03:25:01

+25

谢谢。 'UIBarButtonItem'继承自'UIBarItem'和'NSObject',所以它不知道任何关于触摸的东西。如果文档提到'action'和'target'属性只适用于自定义视图是UIButton的情况,那将会很好。 – 2011-11-18 15:48:23

+12

@JasonMoore:更好的是,如果按钮的行为像...按钮那样会更好,如果它的行为符合程序员的期望,那么就不需要额外的文档 – GeneralMike 2012-12-17 18:43:04

1

雅各,一切看起来不错,但你可能没有提供正确的选择。

您可以验证你的行动实际上是宣告

- (void) deselectAll; 

,而不是

- (void) deselectAll:(id)sender; 

如果是后者,你需要将操作设置为@selector(deselectAll:)。 (注意与分号匹配的分号)

另外,void可能是IBAction,但这与您遇到的这个问题无关。

+0

@ohhorob,我肯定有关该方法的签名。 – 2010-05-09 02:54:47

+0

@ohhorob,我也没有使用IB;) – 2010-05-09 02:56:18

+0

也检查您设置为目标的实例没有被释放和释放。它是导航控制器的子类还是导航层次结构中的另一个视图控制器? – ohhorob 2010-05-09 02:58:51

0

是您的自定义视图吃触摸事件还是将它们传递给父视图?

+0

正如你所看到的,我的自定义视图只是一个简单的ol UIImageView,所以它没有吃任何事件, – 2010-05-09 02:59:15

23

这是我如何使它发挥作用:

UIButton* infoButton = [UIButton buttonWithType: UIButtonTypeInfoLight]; 
[infoButton addTarget:self action:@selector(displayAboutUs) forControlEvents:UIControlEventTouchDown]; 

UIBarButtonItem* itemAboutUs =[[UIBarButtonItem alloc]initWithCustomView:infoButton]; 
… 
7

我也有类似的问题。我最初遵循@drawnonward建议的路径,但当我试图让我的动作在iPad上呈现popover控制器时遇到了麻烦:使用嵌入的UIButton作为自定义视图意味着UIButton是事件的发送者,并且popover控制器的presentPopoverFromBarButtonItem:方法在尝试发送仅适用于实际UIBarButtonItems的消息时崩溃。

我最终找到解决的办法是偷我想用(以下简称“信息”图标)从暴殄天物的UIButton,构建我的UIBarButtonItem如下形象:

// Make the info button use the standard icon and hook it up to work 
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; 
UIBarButtonItem *barButton = [[[UIBarButtonItem alloc]   
     initWithImage:infoButton.currentImage 
       style:UIBarButtonItemStyleBordered 
      target:self 
      action:@selector(showInfo:)] autorelease]; 

使用这个初始化产生酒吧其目标和选择器实际工作的按钮。它比在自定义视图中包装图像更容易,但这只是结冰。

+1

这解决了它对我来说!用于弹出窗口,使用:[myPopover presentPopoverFromBarButtonItem:sender allowedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; – mpemburn 2012-06-08 22:04:54

0

为了使这很容易使用,我创建了的UIBarButtonItem一个类别,它看起来像这样:

@implementation UIBarButtonItem (CustomButtonView) 

- (void)setButtonImage:(UIImage *)image 
{ 
    UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom]; 
    [button setBackgroundImage:image forState:UIControlStateNormal]; 
    [button sizeToFit]; 
    [button addTarget:self.target action:self.action forControlEvents:UIControlEventTouchUpInside]; 
    self.customView = button; 
} 

- (UIImage *)buttonImage 
{ 
    return [(UIButton *)self.customView imageForState:UIControlStateNormal]; 
} 

@end 

在您的客户端代码,只需使用:

myBarButtonItem.buttonImage = [UIImage imagedNamed:@"image_name"]; 

完成这样你就可以仍然在IB中挂钩你的目标和行动(尽可能多地将UI配置推入IB,这是一件好事)。

9

下面是如何实现的UIButton中的UIBarButtonItem内:

UIButton *logoButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
[logoButton setImage: [UIImage imageNamed:@"icon.png"] forState:UIControlStateNormal]; 
logoButton.frame = CGRectMake(0, 0, 30, 30); 
[logoButton addTarget:self action:@selector(showAbout:) forControlEvents:UIControlEventTouchUpInside]; 
UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:logoButton]; 
self.navigationItem.rightBarButtonItem = barItem; 
[barItem release]; 
+0

该解决方案是正确的。我们也可以使用UIButton来添加另一个视图。 – Brave 2015-10-31 21:30:24

21

我有同样的问题,但反对使用UIButton而不是自定义视图我UIBarButtonItem(每drawnonward的反应)。

或者,您可以在使用它初始化UIBarButtonItem之前将UIGestureRecognizer添加到自定义视图;这似乎在我的项目中工作。

这是我会怎样修改原来的代码:

UIImageView *SOCImageView = [[UIImageView alloc] initWithImage: 
          [UIImage imageNamed:@"cancel_wide.png"]]; 

UITapGestureRecognizer *tapGesture = 
     [[UITapGestureRecognizer alloc] initWithTarget:self 
               action:@selector(deselectAll:)]; 
[SOCImageView addGestureRecognizer:tapGesture]; 

SOItem.leftBarButtonItem = 
     [[[UIBarButtonItem alloc] initWithCustomView:SOCImageView] autorelease]; 
[tapGesture release]; 
[SOCImageView release]; 
+0

没有为我工作,只有这个解决方案。自定义视图不允许设置操作。简单的UIButton在显示背景图像时遇到麻烦。有了这个手势识别器,它终于解决了。 – Denis 2014-06-12 15:15:58

+0

添加tapgesture到我的自定义视图不起作用,但它确实工作,当我将它添加到我的酒吧按钮项目。 – Ronaldoh1 2015-05-07 17:51:06

+0

@ Ronaldoh1你是如何将UITapgesture添加到UIBarButtonItem的? – tsuz 2016-04-12 19:21:52

0

斯威夫特3.我有一个类似的问题,我有栏按钮项目内部的自定义视图。为了让点击工作,我为视图分配了一个手势并设置了该操作。这个观点需要成为一个分配给它的出路。这样做与自定义视图一起工作。

设置手势类变量

@IBOutlet weak var incidentView: UIView! 
let incidentTap = UITapGestureRecognizer() 

在viewDidLoad中

incidentTap.addTarget(self, action: #selector(self.changeIncidentBarItem)) 
incidentView.addGestureRecognizer(incidentTap) 
0

如果你不想用的UIImage来解决,而且已经在barbuttonitem自定义视图,设置双击手势识别到您的barbuttonitem的customview属性

let tap = UITapGestureRecognizer(target: self, action: #selector(goProButtonPressed)) deviceStatusBarButtonItem.customView?.addGestureRecognizer(tap)

0

Swift 3:以下是我对按钮自定义和事件处理的完整实现。

override func viewDidLoad() { 
    super.viewDidLoad() 

    let button = UIButton.init(type: .custom) 
    button.setTitle("Tester", for: .normal) 
    button.setTitleColor(.darkGray, for: .normal) 
    button.layer.borderWidth = 1 
    button.layer.cornerRadius = 5 
    button.layer.borderColor = UIColor.darkGray.cgColor 
    button.addTarget(self, action: #selector(self.handleButton), for: .touchUpInside) 

    self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button) 
} 

override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 

    if let button = self.navigationItem.rightBarButtonItem?.customView { 
     button.frame = CGRect(x:0, y:0, width:80, height:34) 
    } 
} 

func handleButton(sender : UIButton) { 
    // It would be nice is isEnabled worked... 
    sender.alpha = sender.alpha == 1.0 ? 0.5 : 1.0 
} 

希望这有助于