定义一次 UIAlertViewController 并在 Objective-C 的不同类中使用它

Posted

技术标签:

【中文标题】定义一次 UIAlertViewController 并在 Objective-C 的不同类中使用它【英文标题】:Define UIAlertViewController once and use it in different classes in Objective-C 【发布时间】:2018-12-21 11:04:53 【问题描述】:

我想知道解决这个问题的方法。

//Modal.h

-(void)errorAlert : (NSString *)title : (NSString *)desc : (NSString *)buttonTitle;


//Modal.m

-(void)errorAlert: (NSString *)title : (NSString *)desc : (NSString *)buttonTitle

    alert = [UIAlertController alertControllerWithTitle:title message:desc preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction *ok = [UIAlertAction actionWithTitle:buttonTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) 

    ];

    [alert addAction:ok];

    [self presentViewController:alert animated:YES completion:nil];


现在我想在其他类中使用这个errorAlert,这样我就不必再次编写警报验证

//Login.m


#import "Modal.m"

@property (strong, nonatomic) Modal *modal;


-(void)viewDidLoad

  _modal = [[Modal alloc] init];





//MARK: Submit Clicked

- (IBAction)submitClicked:(UIButton *)sender 


    // I want to use that method here.


请给我一个出路,以便我可以根据格式优化我的代码。

【问题讨论】:

在Objective-C中使用扩展(称为类别)来允许您的每个UIViewController实现它怎么样?或者可能是子类化(但可能有很多子类要做)。 你能给我推荐一个代码@Larme developer.apple.com/library/archive/documentation/Cocoa/… ***.com/questions/24324021/… 等 我不确定您在问什么...您能否更具体地说明您想要一条出路的问题? 使用协议实现更容易创建单例类。毕竟任何时候都应该有一个 UIAlertController 实例。 【参考方案1】:

正如 cmets 中提到的,这看起来并不是最好的实现。无论如何,回答你的问题:首先,你的方法的签名应该这样修复

-(void)errorAlertWithTitle:(NSString *)title description:(NSString *)desc buttonTitle:(NSString *)buttonTitle fromViewController:(UIViewController *)viewController;

及其实现

-(void)errorAlertWithTitle:(NSString *)title description:(NSString *)desc buttonTitle:(NSString *)buttonTitle fromViewController:(UIViewController *)viewController 
    alert = [UIAlertController alertControllerWithTitle:title message:desc preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *ok = [UIAlertAction actionWithTitle:buttonTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action)];
    [alert addAction:ok];
    [viewController presentViewController:alert animated:YES completion:nil];

然后你只需要在 submitClicked 中调用它

- (IBAction)submitClicked:(UIButton *)sender 
    [self.modal errorAlertWithTitle:@"The title" description:@"The description" buttonTitle:@"ButtonTitle" fromViewController:self];

【讨论】:

它说 - 警告:尝试在 上显示 ,其视图不在窗口层次结构中! @il3v 没错,您必须通过呈现视图控制器:请参阅我审查过的答案。同样,绝对不是最好的实现,而只是您问题的答案 它在这里工作。请务必将 [self presentViewController: 替换为 [viewController presentViewController:.【参考方案2】:

目标-C:

    在 Alert.h 中
(void)showAlertWithTitle:(NSString *)title 
        message:(NSString* _Nullable)message 
        defaultPrompt:(NSString *)defaultPrompt 
        optionalPrompt:(NSString* _Nullable)optionalPrompt 
        defaultHandler:(nullable void(^)(UIAlertAction *))defaultHandler 
        optionalHandler:(nullable void(^)(UIAlertAction *))optionalHandler;
    在 Alert.m 中
    (void)showAlertWithTitle:(NSString *)title message:(NSString* _Nullable)message defaultPrompt:(NSString *)defaultPrompt optionalPrompt:(NSString* _Nullable)optionalPrompt defaultHandler:(nullable void(^)(UIAlertAction *))defaultHandler optionalHandler:(nullable void(^)(UIAlertAction *))optionalHandler 

    // Executing the method in the main thread, since its involving the UI updates.
    dispatch_async(dispatch_get_main_queue(), ^
        UIAlertController* alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];

    [alert addAction:[UIAlertAction actionWithTitle:defaultPrompt style:UIAlertActionStyleDefault handler:defaultHandler]];
    if (optionalPrompt) 
        [alert addAction:[UIAlertAction actionWithTitle:optionalPrompt style:UIAlertActionStyleCancel handler:optionalHandler]];
    
    [[[UIApplication sharedApplication] keyWindow].rootViewController presentViewController:alert animated:true completion:nil];
); 

SWIFT 4.2:

只需创建一个名为 Alert.swift 的新 swift 文件,并在其中定义 AlertController 的通用版本。这样你就可以在项目的任何地方使用它,只需调用Alert.showErrorAlert("", title: "")

import UIKit
import os.log

class Alert 

    /// Display the given error message as an alert pop-up
    /// - parameter errorMessage: The error description
    /// - parameter title: The title of the error alert
    class func showErrorAlert(_ errorMessage: String, title: String?) 
        let alert = UIAlertController(title: title ?? "Error", message: errorMessage, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        guard let rootView = UIApplication.shared.keyWindow?.rootViewController else 
            os_log("Cannot show alert in the root view", log: .default, type: .error)
            return
        
        rootView.present(alert, animated: true, completion: nil)
    



【讨论】:

可以在目标c中 @TheTravloper 在 Objective-C 中添加了实现,请检查并告诉我你的想法。谢谢

以上是关于定义一次 UIAlertViewController 并在 Objective-C 的不同类中使用它的主要内容,如果未能解决你的问题,请参考以下文章

是否可以一次为多个指令定义 $IFDEF ?

多重定义和第一次在我的 C 程序中定义

变量/函数可以声明任意次数,但只能定义一次[重复]

自定义 UIButton 触发 IBAction 一次,然后再也不触发

React checkbox - Onchange 复选框,第一次未定义

第一次选择未定义以 redux 形式选择表单值