【问题标题】:How to fire uibarbuttonitem click event programmatically如何以编程方式触发 uibarbuttonitem 点击事件
【发布时间】:2012-03-18 19:11:29
【问题描述】:

我创建了一个UIActionSheet

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

UIActionSheet 中的取消按钮事件上,我想触发UIBarButtonItem 的事件,这在我看来。

我的问题是如何在UIActionSheet 委托方法中触发按钮事件(不触摸按钮)

【问题讨论】:

  • 当用户点击 UIBarButtonItem 时你调用的是哪个方法?
  • 我的处境很混乱。我在这个UIBarButtonItem 上有一个UIButton。点击UIButton,我加载了UIActionSheet。点击UIActionSheet中的取消按钮,我需要触发UIBarButtonItem的事件。
  • Paul 我不明白,如果你的UIBarButtonItemUIButton 之下,为什么你要创建UIBarButtonItem

标签: iphone ios events uibarbuttonitem uiactionsheet


【解决方案1】:

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

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

【讨论】:

  • 感谢 from nil,因为大多数操作都有发件人
【解决方案2】:

不知道当前的条形按钮项操作,您可以这样调用它:

[barButtonItem.target performSelector:barButtonItem.action]

这将带来“未知选择器”编译器警告,但这可能是worked around

【讨论】:

  • UIBarButtonItem 可能不会回复sendActionsForControlEvents
  • 这里有没有其他人收到 ARC 警告“可能导致泄漏”?
  • 要禁止“可能导致泄漏”警告,请参阅this answer
  • 不,这是绝对有效的情况。你可以使用performSelector:barButtonItem.action,这里没有私有API。
  • Swift 版本:_ = editButton.target?.perform(editButton.action)
【解决方案3】:

@ton1n8o 的解决方案对我有用。这是swift中的实现:

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

【讨论】:

    【解决方案4】:

    我已阅读接受的答案,这非常危险。您永远不应该禁止此类警告以缩短获得所需结果的路径!

    最安全的方法:

    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 may cause a leak because its selector is unknown

    【讨论】:

      【解决方案5】:

      对于我使用 RxCocoa 的情况,我需要为执行操作提供 nil - object,否则它会因 EXC_BAD_ACCESS 而崩溃:

      let button = sut.navigationItem.leftBarButtonItem!
      _ = button.target?.perform(button.action, with: nil)
      

      【讨论】:

        【解决方案6】:

        您可以使用此方法以编程方式为特定按钮触发点击事件:

        [self performSelector:@selector(buttonClicked:) withObject:self.myButton afterDelay:0.0]; 
        

        【讨论】:

          【解决方案7】:

          这就是我使用 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]; 
          }
          

          所以在关闭操作表中,您可以重写栏按钮项内发生的事情...希望这会有所帮助。

          【讨论】:

            【解决方案8】:

            实现委托方法

            - (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,取消 未设置按钮索引。

            讨论 该方法在 动画开始,视图被隐藏。

            【讨论】:

            • 这对我很有帮助。谢谢@Krrish
            猜你喜欢
            • 1970-01-01
            • 2016-06-12
            • 2021-06-04
            • 1970-01-01
            • 2020-10-03
            • 2021-08-14
            • 2019-01-22
            • 1970-01-01
            • 2014-01-24
            相关资源
            最近更新 更多