ios UIBarButtonItem:目标操作不起作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2796438/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:12:46  来源:igfitidea点击:

UIBarButtonItem: target-action not working?

iphoneiosobjective-ccocoa-touch

提问by Jacob Relkin

I've got a custom view inside of a UIBarButtonItem, set by calling -initWithCustomView. My bar button item renders fine, but when I tap it, it doesn't invoke the action on my target object.

我在 a 中有一个自定义视图UIBarButtonItem,通过调用-initWithCustomView. 我的条形按钮项目呈现良好,但是当我点击它时,它不会调用我的目标对象上的操作。

Here's my code:

这是我的代码:

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)];

回答by drawnonward

I do not think the target and action of the UIBarButtonItem apply to custom views. Try using a UIButton instead of UIImageView and applying the target and action to the button.

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

Sample code in Swift:

Swift 中的示例代码:

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

回答by Tim Camber

I had the same problem, but was averse to using a UIButtoninstead of a custom view for my UIBarButtonItem(per drawnonward's response).

我遇到了同样的问题,但反对使用 aUIButton而不是我的自定义视图UIBarButtonItem(根据drawonward的响应)。

Alternatively, you could add a UIGestureRecognizerto the custom view before using it to initialize UIBarButtonItem; this appears to work in my project.

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

This is how I would modify your original code:

这是我修改原始代码的方式:

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];

回答by Nicolas Lauquin

Here is how I make it work:

这是我如何使它工作:

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

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

回答by Zac Witte

Here's how I implemented the UIButton inside of the UIBarButtonItem:

下面是我在 UIBarButtonItem 中实现 UIButton 的方法:

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];

回答by James Elliott

I had a similar problem. And I initially followed the path suggested by @drawnonward, but then ran into trouble when I tried to have my action present a popover controller on an iPad: Using an embedded UIButton as a custom view means the UIButton is the sender of the event, and the popover controller's presentPopoverFromBarButtonItem: method crashes when it tries to send it messages which are only appropriate to actual UIBarButtonItems.

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

The solution I eventually found was to steal the image I wanted to use (the “info” icon) from a throwaway UIButton, and construct my UIBarButtonItem as follows:

我最终找到的解决方案是从一次性 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];

Using this initializer yields a bar button whose target and selector actually work. It is also easier than wrapping the image in a custom view, but that is just icing.

使用这个初始值设定项会产生一个条形按钮,其目标和选择器实际上可以工作。这也比将图像包装在自定义视图中更容易,但这只是锦上添花。

回答by Micah Montoya

Swift 3. I had a similar issue where I had a custom view inside of the bar button item. In order to get the tap to work I assigned a gesture to the view and set the action. The view needed to be an outlet to assign to it. Doing this it worked with the custom view.

Swift 3. 我有一个类似的问题,我在栏按钮项中有一个自定义视图。为了让点击工作,我为视图分配了一个手势并设置了动作。视图需要是分配给它的插座。这样做它与自定义视图一起工作。

Setting the gesture as class variable

将手势设置为类变量

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

In viewDidLoad

在视图中加载

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

回答by Leo

If you do not want to settle with an UIImage and have a custom view in your barbuttonitem, set a tap gesture recognizer to your barbuttonitem's customview property

如果您不想使用 UIImage 并在 barbuttonitem 中有自定义视图,请将点击手势识别器设置为 barbuttonitem 的 customview 属性

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

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

回答by Joe Andolina

Swift 3: Below is my full implementation for button customization and event handling.

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
}

Hope this helps

希望这可以帮助

回答by ohhorob

Jacob, everything looks good, however you may not have provided the correct selector.

Jacob,一切看起来都不错,但是您可能没有提供正确的选择器。

Can you verify that your action is actually declared

您能否验证您的操作是否已实际声明

- (void) deselectAll;

and not

并不是

- (void) deselectAll:(id)sender;

If it's the latter, you will need to set the action to @selector(deselectAll:). (note the semi-colon to match the method declaration)

如果是后者,则需要将操作设置为@selector(deselectAll:)。(注意分号与方法声明相匹配)

Also, void might be IBAction, but that's not relevant to this problem you're having.

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

回答by Alex Reynolds

Is your custom view eating touch events or passing them on to parent view?

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