-3

I want to know a way out for this problem.

//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];

}

Now I want to use this errorAlert in other classes so that I don't have to write the validation for alert again

//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.

}

Please suggest me a way out so that I can optimize my code according to the format.

JimHawkins
  • 4,843
  • 8
  • 35
  • 55
TheTravloper
  • 236
  • 5
  • 16
  • What about using instead an Extension (called Category) in Objective-C, to allow each of your UIViewController to implement it? Or maybe subclassing (but there might be then a lot of subclass to do). – Larme Dec 21 '18 at 11:12
  • can you suggest me a code @Larme – TheTravloper Dec 21 '18 at 11:12
  • https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html https://stackoverflow.com/questions/24324021/how-do-i-create-a-category-in-xcode-6-or-higher etc. – Larme Dec 21 '18 at 11:20
  • I'm not sure what you're asking about... could you be more specific about the problem from which you want *a way out*? – Caleb Dec 21 '18 at 12:03
  • Is easier to create Singleton class with protocol implementation. After all there should really be one instance of UIAlertController at all times. – GeneCode Dec 23 '18 at 23:54

2 Answers2

0

As mentioned in the comments this doesn't really look like the best implementation. Anyway, to answer your question: first of all, the signature of your method should be fixed this way

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

And its implementation

-(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];
}

Then you just have to call it in submitClicked

- (IBAction)submitClicked:(UIButton *)sender {
    [self.modal errorAlertWithTitle:@"The title" description:@"The description" buttonTitle:@"ButtonTitle" fromViewController:self];
}
il3v
  • 472
  • 4
  • 15
  • it says - Warning: Attempt to present on whose view is not in the window hierarchy! @il3v – TheTravloper Dec 21 '18 at 11:43
  • that's correct, you have to pass the presenting view controller: please see my reviewed answer. Again, definitely not the best implementation but just an answer to your question – il3v Dec 21 '18 at 15:11
  • It works here. Please be sure to replace *[self presentViewController:* with *[viewController presentViewController:*. – il3v Dec 24 '18 at 09:07
0

OBJECTIVE-C:

  1. In 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;
  1. In 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:

Just create a new swift file named Alert.swift and define the generalized version of AlertController in it. In this way you could use it anywhere in the project just by calling 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)
    }


}
Daniel Selvan
  • 959
  • 10
  • 23