xcode 以编程方式触发 UIAlertController 的 UIAlertAction

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

Trigger UIAlertAction of a UIAlertController programmatically

iosxcode

提问by CharlesA

I want to dismiss my UIAlertController with a click on the 'Cancel' button when my app goes in to background.

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

I've set up the background notification with

我已经设置了后台通知

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

Then in my appDidEnterBackground function I have:

然后在我的 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];
    }
}

What I'm struggling with is how to trigger the UIAlertAction programmatically. Is this possible?

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

采纳答案by CharlesA

I answered this with using the suggestion made by MCKapur.

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

I already had the UIAlertController in a singleton. What I did was define a variable in my singleton to save the completion action:

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

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

Then when I set up the UIAlertController to show it, I also setup the completion code with:

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

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

Finally, I changed the appDidEnterBackground call to:

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

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

回答by Tony Langdon

This is old but it is the top result when looking for how to trigger a UIAlertAction programmatically.

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

Just in case anyone (still doing objC) is prepared to use internal methods - this works with iOS 10 and 11:

以防万一有人(仍在使用 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];
}