如何以编程方式触发uibarbuttonitem的点击事件

20

我已经创建了一个 UIActionSheet

UIActionSheet * action = [[UIActionSheet alloc]initWithTitle:@""
                                                              delegate:self
                                                     cancelButtonTitle: @"cancel"
                                                destructiveButtonTitle: @"OK"
                                                     otherButtonTitles: nil];
          [action showInView:self.view];
          [action release];

UIActionSheet中的取消按钮事件触发时,我想要触发我的视图中的UIBarButtonItem事件。

我的问题是如何在UIActionSheet委托方法中触发这个按钮事件(而不是点击这个按钮)。


当用户点击UIBarButtonItem时,你调用的是哪个方法? - Rupesh
我处于一种混乱的情况中。我的UIButton覆盖在UIBarButtonItem上面。当点击UIButton时,我加载了一个UIActionSheet。而当在UIActionSheet中点击取消按钮时,我需要触发UIBarButtonItem的事件。 - Jean Paul
Paul,我不明白为什么你要创建 UIBarButtonItem,如果你的 UIBarButtonItemUIButton 下面? - hchouhan02
8个回答

28

另一种避免警告的方法如下:

[[UIApplication sharedApplication] sendAction:barButtonItem.action
                                           to:barButtonItem.target
                                         from:nil
                                     forEvent:nil];

感谢 nil 的存在,因为大多数操作都有发送者。 - Mutawe

18

如果不知道当前的导航栏按钮可以执行什么操作,您可以通过以下方式调用它:

[barButtonItem.target performSelector:barButtonItem.action]

但这会引起“未知选择器”编译警告,不过这可能可以通过解决


UIBarButtonItem еЏЇиѓЅж— жі•е“Ќеє” sendActionsForControlEventsгЂ‚ - Jean Paul
5
这里是否还有其他人收到 ARC 警告:“可能会引起泄漏”? - anders
为了消除“可能导致泄漏”警告,请参阅此答案 - Pang
不,这是非常有效的情况。您可以使用performSelector:barButtonItem.action,这里没有私有API使用。 - ayoy
2
Swift 版本:_ = editButton.target?.perform(editButton.action) - nickromano

14

@ton1n8o的解决方案对我很有用。这是Swift语言的实现:

UIApplication.sharedApplication().sendAction(barButtonItem.action, to: barButtonItem.target, from: nil, forEvent: nil)

2
我已经阅读了被接受的答案,它非常危险。为了快速达到你想要的结果,你绝不能压制这样的警告!最安全的方法是:
SEL selector=barButton.action;
id target=barButton.target;
  if(selector && target){
     IMP imp = [target methodForSelector:selector];
     void (*func)(id, SEL) = (void *)imp;
     func(target, selector);
  }

请阅读原帖: performSelector可能会导致泄漏,因为其选择器未知


2

对于我使用的RxCocoa,我需要提供一个nil-object来执行操作,否则它会崩溃并显示EXC_BAD_ACCESS

最初的回答:在我的情况下,使用RxCocoa时,如果不提供一个nil对象来执行操作,它就会崩溃并显示EXC_BAD_ACCESS。
let button = sut.navigationItem.leftBarButtonItem!
_ = button.target?.perform(button.action, with: nil)

1
您可以使用此方法来以编程方式触发特定按钮的tap事件:
[self performSelector:@selector(buttonClicked:) withObject:self.myButton afterDelay:0.0]; 

0

这就是我如何使用 actionSheet..

actionSheet  = [[UIActionSheet alloc] initWithTitle:nil 
                                                             delegate:nil
                                                    cancelButtonTitle:nil
                                               destructiveButtonTitle:nil
                                                    otherButtonTitles:nil];

[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];

CGRect pickerFrame = CGRectMake(0, 40, 0, 0);

UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
pickerView.showsSelectionIndicator = YES;
pickerView.dataSource = self;
pickerView.delegate = self;

[actionSheet addSubview:pickerView];
[pickerView release];

UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:@"Done"]];
closeButton.momentary = YES; 
closeButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
closeButton.segmentedControlStyle = UISegmentedControlStyleBar;
closeButton.tintColor = [UIColor blackColor];
[closeButton addTarget:self action:@selector(dismissActionSheet) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:closeButton];
[closeButton release];

[actionSheet showInView:[[UIApplication sharedApplication] keyWindow]];

[actionSheet setBounds:CGRectMake(0, 0, 320, 485)];

完成后,只需在您的 .m 文件中定义一个选择器,如下所示...

-(void)dismissActionSheet{
    [actionSheet dismissWithClickedButtonIndex:0 animated:YES]; 
}

所以在取消操作表内,你可以重新编写在工具栏按钮项中发生的事情... 希望这能帮到你。


0

实现委托方法

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex

或者

- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex
{
    if(buttonIndex == actionSheet.destructiveButtonIndex)
    {

    }
    else if(buttonIndex == (actionSheet.cancelButtonIndex))
    {
        // Call your event here
        // Fire the event of UIBarButtonItem.
    }

}

actionSheet:didDismissWithButtonIndex:

在操作表从屏幕中消失后发送给委托。

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex Parameters

actionSheet 已经消失的操作表。buttonIndex 被点击的按钮的索引。按钮索引从0开始。如果这是取消按钮索引,则操作表正在取消。如果为-1,则未设置取消按钮索引。

讨论:此方法在动画结束并隐藏视图后调用。

actionSheet:willDismissWithButtonIndex:

在操作表将要消失之前发送给委托。

- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex Parameters

actionSheet 将要被取消的操作表。buttonIndex 被点击的按钮的索引。如果这是取消按钮索引,则操作表正在取消。如果为-1,则未设置取消按钮索引。

讨论:此方法在动画开始并隐藏视图之前调用。


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