【问题标题】:Trigger UIAlertAction of a UIAlertController programmatically以编程方式触发 UIAlertController 的 UIAlertAction
【发布时间】:2018-08-27 08:16:52
【问题描述】:

当我的应用进入后台时,我想通过单击“取消”按钮来关闭我的 UIAlertController。

我已经设置了后台通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];

然后在我的 appDidEnterBackground 函数中我有:

- (void)appDidEnterBackground {
    if (_alertController) {
        UIAlertAction *cancelAction = [[_alertController actions] objectAtIndex:0];

        //HERE: is there a way to trigger the cancelAction??

        [_alertController dismissViewControllerAnimated:NO completion:nil];
    }
}

我正在努力解决的是如何以编程方式触发 UIAlertAction。这可能吗?

【问题讨论】:

  • 我认为您不能以编程方式触发您的UIAlertAction 的按下。您可以尝试复制代码,或者将其分支到全局声明的方法中?
  • @MCKapur 您的第二点很有潜力。我已经为 UIAlertController (/UIAlertView for iOS7) 使用了单例,因此这些操作已经在全局范围内定义。如何在全局范围内存储一个块,以便在应用程序进入后台时调用它?
  • @MCKapur 破解了它——我在我的单例中添加了一个 var 来保存完成块操作。然后我打电话给appDidEnterBackground。如果您作为答案发布,我会接受。
  • 太棒了,很高兴听到!没关系 - 我不在乎,只要你解决了你的问题。

标签: ios xcode


【解决方案1】:

我使用 MCKapur 的建议回答了这个问题。

我已经在单例中拥有 UIAlertController。我所做的是在我的单例中定义一个变量来保存完成操作:

@property (copy, nonatomic) void (^completion)(BOOL);

然后,当我设置 UIAlertController 以显示它时,我还设置了完成代码:

_completion = ^(BOOL cancelled) {
    if (block) {
        block (NO, nil);
    }
};

最后,我将 appDidEnterBackground 调用更改为:

- (void)appDidEnterBackground {
    if (_alertController) {
        if (_completion) {
            _completion(NO);
            _completion = nil;
        }
        [_alertController dismissViewControllerAnimated:NO completion:nil];
    }
}

【讨论】:

    【解决方案2】:

    这是旧的,但它是寻找如何以编程方式触发 UIAlertAction 时的最佳结果。

    以防万一任何人(仍在使用 objC)准备使用内部方法 - 这适用于 iOS 10 和 11:

    - (void)triggerAction:(UIAlertAction*)action onAlertController:(UIAlertController*)alert {
        SEL triggerSelector = NSSelectorFromString(@"_dismissAnimated:triggeringAction:triggeredByPopoverDimmingView:dismissCompletion:");
        NSMethodSignature* signature = [[alert class] instanceMethodSignatureForSelector:triggerSelector];
        if (!signature) {
            // Try pre iOS11 - OK as we're not trying to use the completion block
            triggerSelector = NSSelectorFromString(@"_dismissAnimated:triggeringAction:triggeredByPopoverDimmingView:");
            signature = [[alert class] instanceMethodSignatureForSelector:triggerSelector];
        }
        NSAssert(signature != nil, @"Couldn't find trigger method");
        NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
        [invocation setTarget:alert];
        [invocation setSelector:triggerSelector];
        BOOL boolValue = YES; // Animated & dimmingView
        [invocation setArgument:&boolValue atIndex:2];
        [invocation setArgument:&action atIndex:3];
        [invocation setArgument:&boolValue atIndex:4];
        // Not setting anything for the dismissCompletion block atIndex:5
        [invocation invoke];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-01
      • 2019-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多