代码之家  ›  专栏  ›  技术社区  ›  user6631314

iOS/Objective-C:从sharedInstance调用AlertViewController

  •  1
  • user6631314  · 技术社区  · 6 年前

    使用UIAlertView,可以从正在执行的任何代码(即使是在实用程序类或共享实例中)抛出一个警报,只需简单的一行:

    [alertView show];
    

    所以如果我调用一个共享实例,比如

    - (void)didTapDeleteButton:(id)sender {
        NSArray *itemsToDelete = [self.selectedIndexPathToContact allValues];
    
        [[IDModel sharedInstance] deleteItems:itemsToDelete];
    

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Keep Archive Copy?"
                                                        message:nil
                                                       delegate:self
                                              cancelButtonTitle:@"No"
                                              otherButtonTitles:@"OK",nil];
    alertInvite.alertViewStyle = UIAlertViewStyleDefault;
    alertInvite.tag=100;
    [alertView show];
    

    一切正常。

    但是,对于UIAlertController,这是不允许的。如果将以下代码放入可通过共享实例访问的类的方法中,当您到达presentViewController时,它将抛出一个错误:

    UIAlertController *alertView = [UIAlertController alertControllerWithTitle:@"Delete Item?" message:nil preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction* yesButton = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
        [alertView dismissViewControllerAnimated:YES completion:nil];
    }];
    
    UIAlertAction* noButton = [UIAlertAction actionWithTitle:@"Not Now" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
        [alertView dismissViewControllerAnimated:YES completion:nil];
    }];
    
    [alertView addAction:noButton];
    [alertView addAction:yesButton];
    if ([alertView respondsToSelector:@selector(setPreferredAction:)]) {
        [alertView setPreferredAction:yesButton];
    }
    //FOLLOWING THROWS ERROR
    [self presentViewController:alertView animated:YES completion:nil];
    

    在最后一行,类(通过共享实例到达)没有此方法。看来你必须用更复杂的方法来发出警报。我见过一些 somwehat convoluted approaches 例如:

    id rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
    if([rootViewController isKindOfClass:[UINavigationController class]])
    {
        rootViewController = ((UINavigationController *)rootViewController).viewControllers.firstObject;
    }
    if([rootViewController isKindOfClass:[UITabBarController class]])
    {
        rootViewController = ((UITabBarController *)rootViewController).selectedViewController;
    }
    [rootViewController presentViewController:alertInvite animated:YES completion:nil];
    

    3 回复  |  直到 6 年前
        1
  •  1
  •   Sean Kladek    6 年前

    我在UIViewController上创建了一个扩展,它允许我创建一个新窗口并从那里显示一个视图控制器。这允许我从任何类中呈现,而不仅仅是视图控制器。此外,它还防止了试图从已经呈现视图控制器的视图控制器中显示警报视图的问题。

    extension UIViewController {
        func presentFromNewWindow(animated: Bool = true, completion: (() -> Void)? = nil) {
            let window = newWindow()
    
            if let rootViewController = window.rootViewController {
                window.makeKeyAndVisible()
                rootViewController.present(self, animated: animated, completion: completion)
            }
        }
    
        private func newWindow() -> UIWindow {
            let window = UIWindow(frame: UIScreen.main.bounds)
            let rootViewController = UIViewController()
            rootViewController.view.backgroundColor = .clear
            window.backgroundColor = .clear
            window.rootViewController = rootViewController
            window.windowLevel = UIWindowLevelAlert
    
            return window
        }
    }
    

    然后可以使用此方法显示警报控制器(或任何UIViewController):

    alertViewController.presentFromNewWindow()
    

        2
  •  1
  •   Daij-Djan    6 年前

    要显示我可以想到执行的任何代码的警报:

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Alert" message:@"message" preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction: [UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:nil]];
    alert.TitleColor = [UIColor whiteColor];
    
    id<UIApplicationDelegate> delegate = [UIApplication sharedApplication].delegate;
    UIViewController *vc = delegate.window.rootViewController;
    [vc presentViewController:alert animated:YES completion:nil];
    

    注:

    请注意,在大多数情况下,我不会这样做。

        3
  •  0
  •   Glenn Posadas    6 年前

    我相信你的问题很含糊。但我认为你一直在寻找的是 UIAlertController . 是这样吗?如果是,继续阅读。。。

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Alert" message:@"message" preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction: [UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:nil]];
    alert.TitleColor = [UIColor whiteColor];
    [self presentViewController:alert animated:YES completion:nil];
    

    文件: https://developer.apple.com/documentation/uikit/uialertcontroller