-3

in the simple language: can we create that alert Box as a reusable method AlertBox

i want to made 1 Alert box in to the function. like this.

// this code has separate file 

import UIKit

struct AlertView {
    public func showAlertBox(title: String, message: String) -> UIAlertController {
         let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
         alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { _ in
       }))
    return alert
  }
}

and here is my caller ViewController file code.

 @IBAction func submitPressed(_ sender: Any) {
     let alertView = AlertView()
     let alert = alertView.showAlertBox(title: "Hours Added", message: "Hours have been updated")
     alert.present(alert, animated: true) {
         self?.dismiss(animated: true, completion: nil)
         self?.timeSubmitted = true
         self?.performSegue(withIdentifier: "unwindToMyHours", sender: nil)
     }
 }

4 Answers4

1

You need alert action to performing ok action.

You can modify your code by this

Here are the helper functions.

struct AlertView {
    public static func showAlertBox(title: String, message: String, handler: ((UIAlertAction)->Void)?) -> UIAlertController {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: handler))
        return alert
    }
}

extension UIAlertController {
    func present(on viewController: UIViewController, completion: (() -> Void)? = nil) {
        viewController.present(self, animated: true, completion: completion)
    }
}

Usage

class ViewController: UIViewController {
    
    @IBAction func submitPressed(_ sender: Any) {
        AlertView.showAlertBox(title: "Hours Added", message: "Hours have been updated") { [weak self] action in
            // Okay action code
        }.present(on: self) { [weak self] in
            self?.dismiss(animated: true, completion: nil)
            self?.timeSubmitted = true
            self?.performSegue(withIdentifier: "unwindToMyHours", sender: nil)
        }
    }
}
Note: self is dismissing so might be your alert is not presenting. You can present your alert on top most view controller. see this
Raja Kishan
  • 16,767
  • 2
  • 26
  • 52
0

Yes, you can create a shared alert controller. I would suggest making it a static method of your struct, or even a global function. It's silly to create an instance of your struct only to invoke a method that doesn't need any instance variables:

    public static func alertBox(title: String, message: String) -> UIAlertController {
         let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
         alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { _ in
       }))
    return alert
  }
}

And then you'd invoke it by saying

let alert = AlertView.alertBox(title: "title",message: "message" )

(Your function doesn't show the alert, it just creates it. I would therefore suggest naming it alertBox, not 'showAlertBox`.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
0

Yes, you can use a shared alert controller. What I would suggest is making the AlertView struct, a singleton. You can change the struct as follows

struct AlertView {
    
    // Shared instance
    static let shared: AlertView = AlertView()

    // Private initializer to prevent creating of new instances
    private init() {}

    public func showAlertBox(title: String, message: String) -> UIAlertController {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { _ in
        }))
        return alert
    }
}

By doing so, you will be able to create just one instance of AlertView and you have to use that single instance in your program. That way you won't have to create new instances of AlertView every time you need to display an alert. You can invoke it using,

let alert = AlertView.shared.showAlertBox(title: "Hours Added", message: "Hours have been updated")

Edit - You can refer this medium article to understand the singleton design patter

Visal Rajapakse
  • 1,718
  • 1
  • 9
  • 15
0

The best way is to perform simple encapsulation through extension, and complex encapsulation just loses applicability

example:

        let alertVC = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
        .addActionTitles(titles) { (alertVC, action) in
            let actionIdx = alertVC.actions.firstIndex(of: action)
            DDLog(actionIdx)
        }
        self.present(alertVC, animated: true, completion:{})

code:

public let kTitleSure    = "Yes"
public let kTitleCancell = "No"
/// contentViewController
public let kAlertContentViewController = "contentViewController"

@objc public extension UIAlertController{

    ///add UIAlertAction
    @discardableResult
    func addActionTitles(_ titles: [String]? = [kTitleCancell, kTitleSure], handler: ((UIAlertController, UIAlertAction) -> Void)? = nil) -> Self {
        titles?.forEach({ (string) in
            let style: UIAlertAction.Style = string == kTitleCancell ? .cancel : .default
            self.addAction(UIAlertAction(title: string, style: style, handler: { (action) in
                handler?(self, action)
            }))
        })
        return self
    }
    ///add textField
    @discardableResult
    func addTextFieldPlaceholders(_ placeholders: [String]?, handler: ((UITextField) -> Void)? = nil) -> Self {
        if self.preferredStyle != .alert {
            return self
        }
        placeholders?.forEach({ (string) in
            self.addTextField { (textField: UITextField) in
                textField.placeholder = string
                handler?(textField)
            }
        })
        return self
    }

    @discardableResult
    func setContent(vc: UIViewController, height: CGFloat) -> Self {
        setValue(vc, forKey: kAlertContentViewController)
        vc.preferredContentSize.height = height
        preferredContentSize.height = height
        return self
    }
}

github

Alexander
  • 91
  • 4