Accessing the camera by Actionsheet option - swift

I'm trying to give the user two options uploading an image, the first the the photo library, and the second is the camera. I have an Actionsheet where the user can choose which way he wants to upload an image, but when clicking on the camera option, the camera app won't open. I did add the Privacy needed in the plist file.
This is my actionsheet code:
extension MoreReportsVC: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func handleAddPhoto() {
showSimpleActionSheet(controller: self)
}
func showSimpleActionSheet(controller: UIViewController) {
let alert = UIAlertController(title: "Add a photo", message: "Please Select an option", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "From photo library", style: .default, handler: { (_) in
self.imagePicker.getImage(fromSourceType: .photoLibrary)
}))
alert.addAction(UIAlertAction(title: "Open camera app", style: .default, handler: { (_) in
self.imagePicker.getImage(fromSourceType: .camera)
}))
alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel, handler: { (_) in
print("User click Dismiss button")
}))
self.present(alert, animated: true, completion: {
print("completion block")
})
}
}
This is my ImagePicker code:
class ImagePickerManager: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
var placeholderImage: UIImageView?
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
//TODO:
}
func getImage(fromSourceType sourceType: UIImagePickerController.SourceType){
if UIImagePickerController.isSourceTypeAvailable(sourceType){
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = sourceType
self.present(imagePickerController, animated: true, completion: nil)
}
}
}
The imagePicker in the actionsheet, is just a ImagePickerManager variable.
The app won't crash or anything, and it is getting to the getImage method, but just don't open the camera.
EDIT: I think the problem is in the delegate = self. self needs to be the VC I try to view the imagepicker from if im not wrong. and currently it is ImagePickerManager but I can't find a way to set it as my VC.

The problem is that your ImagePickerManager isn't actually a reference to any view controller currently in the interface. Thus, self.present does nothing because self is not the current view controller.
If you want to put image picker management into an encapsulated class that is not the current view controller, the encapsulation should not itself be a view controller; it should just be an ordinary object. You then won't be able to say self.present, so you will need to provide this object with a reference to the current view controller, which is in this case your MoreReportsVC.

Add getImage method in UIViewController extension like this.
extenstion UIViewController {
func getImage(fromSourceType sourceType: UIImagePickerController.SourceType){
if UIImagePickerController.isSourceTypeAvailable(sourceType){
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = sourceType
self.present(imagePickerController, animated: true, completion: nil)
} else {
print("Source type isn't available")
}
}
}
And call this method from showSimpleActionSheet method from self
func showSimpleActionSheet(controller: UIViewController) {
let alert = UIAlertController(title: "Add a photo", message: "Please Select an option", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "From photo library", style: .default, handler: { (_) in
self.getImage(fromSourceType: .photoLibrary)
}))
alert.addAction(UIAlertAction(title: "Open camera app", style: .default, handler: { (_) in
self.getImage(fromSourceType: .camera)
}))
alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel, handler: { (_) in
print("User click Dismiss button")
}))
self.present(alert, animated: true, completion: {
print("completion block")
})
}
}

Related

Alert not showing in the ImagePicker

I want to offer the option to use either the photo library or the camera, but my alert to select either photos or use a camera doesn't show up when I add the present actionSheet. The compiled application goes straight to photo album without giving me the option to select camera or photo library.
This is the log from my Xcode 11:
2020-06-15 23:05:22.931477-0400 MeMe[6298:3505455] Attempt to present
on which is waiting for a delayed presention of
to complete 2020-06-15
23:05:22.931653-0400 MeMe[6298:3505455] Attempt to present
on
which is waiting for a delayed presention of to complete error in connection_block_invoke_2:
Connection interrupted
This is my code:
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate,
UINavigationControllerDelegate {
// OUTLETS *******************************************
// Image
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
// ACTIONS *******************************************
// Button
#IBAction func pickImage(_ sender: Any) {
let imagePickerController = UIImagePickerController()
// set imagePickerController as delegate
imagePickerController.delegate = self
// provide actionSheet to display the camera and photo options
let actionSheet = UIAlertController(title: "Source", message: "Take a picture or select a photo", preferredStyle: .actionSheet)
// add camera action to imagePickerController
actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler:{(action:UIAlertAction) in
// check if the camera is available
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePickerController.sourceType = .camera
}
else {
print("Camera not available")
}
}))
self.present(imagePickerController, animated: true, completion: nil)
// add photos action to imagePickerController
actionSheet.addAction(UIAlertAction(title: "Photos", style: .default, handler:{(action:UIAlertAction) in imagePickerController.sourceType = .photoLibrary}))
self.present(imagePickerController, animated: true, completion: nil)
// cancel
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
// assign image to imageView
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
imageView.image = image
picker.dismiss(animated: true, completion: nil)
}
// dismiss the image selector
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
}
You're trying to present the actionSheet after presenting imagePickerController which is not possible. You need to present the imagePickerController in the UIAlertAction's handler block. Here's the code:
#IBAction func pickImage(_ sender: Any) {
let imagePickerController = UIImagePickerController()
// set imagePickerController as delegate
imagePickerController.delegate = self
// provide actionSheet to display the camera and photo options
let actionSheet = UIAlertController(title: "Source", message: "Take a picture or select a photo", preferredStyle: .actionSheet)
// add camera action to imagePickerController
actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler:{(action:UIAlertAction) in
// check if the camera is available
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePickerController.sourceType = .camera
}
else {
print("Camera not available")
}
self.present(imagePickerController, animated: true, completion: nil)
}))
// add photos action to imagePickerController
actionSheet.addAction(UIAlertAction(title: "Photos", style: .default, handler:{(action:UIAlertAction) in
imagePickerController.sourceType = .photoLibrary
self.present(imagePickerController, animated: true, completion: nil)
}))
// cancel
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
#IBAction func pickImage(_ sender: Any) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
let actionSheet = UIAlertController(title: "Source", message: "Take a picture or select a photo", preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler:{(action:UIAlertAction) in
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePickerController.sourceType = .camera
self.present(imagePickerController, animated: true, completion: nil)
} else {
print("Camera not available")
}
}))
actionSheet.addAction(UIAlertAction(title: "Photos", style: .default, handler:{(action:UIAlertAction) in
imagePickerController.sourceType = .photoLibrary
self.present(imagePickerController, animated: true, completion: nil)
}))
// cancel
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}

Can't Save UIImage on UIViewController

I've tried to save UIImage on UIViewcontroller named secondViewController, But didn't work.
Code snippet for saving image is attached.
#IBAction func takePhoto(_ sender: Any) {
cameraSession.stopRunning()
UIImageWriteToSavedPhotosAlbum(self.cameraImageView.image!, nil, nil, nil)
}
On SecondViewController, UIImage has been saved to cameraImageView.image,
But when check camera roll, nothing saved.
Does anyone know why?
Add Permission in your info.plist
"Privacy - Photo Library Additions Usage Description"
After permission granted try to save image.
#IBAction func takePhoto(_ sender: Any) {
cameraSession.stopRunning()
UIImageWriteToSavedPhotosAlbum(self.cameraImageView.image!, nil, nil, nil)
}
hey I added full code to capture image using UIImagePickerController and also added code to import a photo from photo gallery, hope it will helpful for you
import UIImagePickerControllerDelegateand create a variable to assign UIImagePickerController var imagePicker = UIImagePickerController()
and set imagePicker.delegate = self.
Create a action sheet to display options for 'Camera' and 'Photo library'.
On your button click action:
#IBAction func buttonOnClick(_ sender: UIButton)
{
self.btnEdit.setTitleColor(UIColor.white, for: .normal)
self.btnEdit.isUserInteractionEnabled = true
let alert = UIAlertController(title: "Choose Image", message: nil, preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { _ in
self.openCamera()
}))
alert.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { _ in
self.openGallary()
}))
alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil))
/*If you want work actionsheet on ipad
then you have to use popoverPresentationController to present the actionsheet,
otherwise app will crash on iPad */
switch UIDevice.current.userInterfaceIdiom {
case .pad:
alert.popoverPresentationController?.sourceView = sender
alert.popoverPresentationController?.sourceRect = sender.bounds
alert.popoverPresentationController?.permittedArrowDirections = .up
default:
break
}
self.present(alert, animated: true, completion: nil)
}
func openCamera() {
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.camera))
{
imagePicker.sourceType = UIImagePickerControllerSourceType.camera
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
else
{
let alert = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
func openGallary() {
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}

How to create a reusable UIAlert ActionSheet as an UIViewController extension?

I would like to create an action sheet that can be used several time in my code. To do so, I need to be able to use functions according to the action sheet title. Is there a way to pass functions as a parameter array like the "title" parameter?
//MARK: - UIAlert action sheet title
enum ActionSheetLabel: String {
case camera = "Camera"
case photoLibrary = "Album"
case cancel = "Cancel"
}
class CameraHandler {
static let cameraHandler = CameraHandler()
func openCamera() { }
func openPhotoLibrary() { }
}
//MARK: - Alert that shows an action sheet with cancel
extension UIViewController {
func showActionSheetWithCancel(vc: UIViewController, title: [ActionSheetLabel] /*Make a function parameter here to match title*/) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for value in title {
actionSheet.addAction(UIAlertAction(title: value.rawValue, style: .default, handler: {
(alert: UIAlertAction!) -> Void in
//Use the parameter function here to match title
}))
}
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel, handler: nil))
vc.present(actionSheet, animated: true, completion: nil)
}
}
For UIAlert you just need to change preferredStyle .alert it and it's working for UIAlert And and below code just copy and paste it working for UIActionSheet.
extension UIViewController {
func popupAlert(title: String?, message: String?, actionTitles:[String?], actionStyle:[UIAlertAction.Style], actions:[((UIAlertAction) -> Void)?]) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .actionSheet)
for (index, title) in actionTitles.enumerated() {
let action = UIAlertAction(title: title, style: actionStyle[index], handler: actions[index])
alert.addAction(action)
}
self.present(alert, animated: true, completion: nil)
}
}
Check below code For Usage
self.popupAlert(title: "Alert"), message: “Error in Loading”, actionTitles: ["Okey", "Email"], actionStyle: [.default, .default], actions: [nil,{ action in
// I have set nil for first button click
// do your code for second button click
}])
if you have any query then please comment me. Thank You
I have find out the best way to add an action sheet with cancel and as much action as needed.
Create an UIViewController extension with type alias:
//MARK: - Alert that shows an action sheet with cancel
extension UIViewController {
typealias AlertAction = () -> ()
typealias AlertButtonAction = (ActionSheetLabel, AlertAction)
func showActionSheetWithCancel(titleAndAction: [AlertButtonAction]) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for value in titleAndAction {
actionSheet.addAction(UIAlertAction(title: value.0.rawValue, style: .default, handler: {
(alert: UIAlertAction!) -> Void in
value.1()
}))
}
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
}
Then, in the class or other place where you want to use it, add the method this way:
//MARK: - UIAlert action sheet title
enum ActionSheetLabel: String {
case camera = "Camera"
case photoLibrary = "Album"
case cancel = "Cancel"
}
//MARK: - Class example where to use the action sheet action
class CameraHandler {
fileprivate let currentVC: UIViewController!
func openCamera() {
// Open user camera
}
func openPhotoLibrary() {
// Open user photo library
}
// Method example of this action sheet
func showActionSheetWithCameraAndLibrary(vc: UIViewController) {
//This is the way to use the extension
vc.showActionSheetWithCancel(titleAndAction: [
(ActionSheetLabel.camera, { [weak self] in self?.openCamera() }),
(ActionSheetLabel.photoLibrary, { [weak self] in self?.openPhotoLibrary() })
])
}
}
You can pass a closure and call it in the handler something like this should work.
Also not sure why you were passing the UIViewController , as you're already defining the function in a extension UIViewController therefore i allowed my self to remove it and used self.present instead .
extension UIViewController {
func showActionSheetWithCancel(title: [ActionSheetLabel], action: #escaping () -> ()?) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
for value in title {
actionSheet.addAction(UIAlertAction(title: value.rawValue, style: .default, handler: {
(alert: UIAlertAction!) -> Void in
// action
action()
}))
}
let alertAction = UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel) { (_) in
action() // or for cancel call it here
}
actionSheet.addAction(alertAction)
self.present(actionSheet, animated: true, completion: nil)
}
}
As you can see #escaping () -> ()? is optional so you can pass nil too .
from what I understood you need to call a specific functions when the title of the alert changes & also you want to be able to do so from different viewControllers,
I hope this will help
extension UIViewController {
func showActionSheetWithCancel(vc: UIViewController, title: [ActionSheetLabel] ) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cameraHandler = CameraHandler()
for value in title {
switch value.rawValue {
case ActionSheetLabel.camera.rawValue:
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.camera.rawValue, style: .default, handler: { (alert) in
cameraHandler.openCamera()
}))
case ActionSheetLabel.photoLibrary.rawValue:
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.photoLibrary.rawValue, style: .default, handler: { (alert) in
cameraHandler.openPhotoLibrary()
}))
default:
actionSheet.addAction(UIAlertAction(title: ActionSheetLabel.cancel.rawValue, style: .cancel, handler: nil))
}
vc.present(actionSheet, animated: true, completion: nil)
}
}
}
and the call of the function will be like this:
showActionSheetWithCancel(vc: self, title: [UIViewController.ActionSheetLabel.camera])

UIAlertController on button click

Opening the UIAlertController on button click, the action is going to open but main issue is the UIAlertAction methods are not performed on its click. Here is Code block :
class HomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// getData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//menuBtn is the button
#IBAction func menuBtn(sender: UIButton) {
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
let orders = UIAlertAction(title: "Orders", style: .Default, handler: { (alert: UIAlertAction!) -> Void in
let alertViewController = self.storyboard?.instantiateViewControllerWithIdentifier("OrdersViewController") as! OrdersViewController
self.presentViewController(alertViewController, animated: true, completion: nil)
})
let about = UIAlertAction(title: "About", style: .Default, handler: {(alert: UIAlertAction!) -> Void in
let aboutObject = self.storyboard?.instantiateViewControllerWithIdentifier("AboutViewController") as! AboutViewController
self.presentViewController(aboutObject, animated: true, completion: nil)
})
let contactUs = UIAlertAction(title: "Contact Us", style: .Default, handler: {(alert: UIAlertAction!) -> Void in
let alertViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ContactViewController") as! ContactViewController
self.presentViewController(alertViewController, animated: true, completion: nil)
})
let login = UIAlertAction(title: "LogIn", style: .Default, handler: {(alert: UIAlertAction!) -> Void in
let alertViewController = self.storyboard?.instantiateViewControllerWithIdentifier("LoginViewController") as! LoginViewController
self.presentViewController(alertViewController, animated: true, completion: nil)
})
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
optionMenu.addAction(orders)
optionMenu.addAction(about)
optionMenu.addAction(contactUs)
optionMenu.addAction(login)
optionMenu.addAction(cancelAction)
self.presentViewController(optionMenu, animated: true, completion: nil)
}
This is code is working fine, I have checked it's opening new viewController as well.
Cross check points:
Controller class and stroybaord are connected
Storyboard ID has been assigned
IBAction must be connected to IBOutlet
On the Button click Action you have to write code.. Try This code.
let alert = UIAlertController(title: "Saved", message: "Selected Frame is Saved", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Ok", style:.Default , handler: { (UIAlertAction) in
}))
//Add action like this
self.presentViewController(alert, animated: true, completion: nil)
Still need any help feel free to ask.
First of all check if the button action is touch up inside. Make the button action as touch up inside. Below code works for me. Hope this works for you as well. Change the action title according to your need.
#IBAction func menuBtn(sender: AnyObject) {
let actionSheet = UIAlertController()
let criticalAction = UIAlertAction(title : "CRITICAL" , style : UIAlertActionStyle.Default){
(action) in
//This section will be executed when the buttons are pressed
//Do your work here.
debugPrint("CRITICAL")
}
let highAction = UIAlertAction(title : "HIGH" , style : UIAlertActionStyle.Default){
(action) in
//This section will be executed when the buttons are pressed
//Do your work here.
debugPrint("HIGH")
}
actionSheet.addAction(criticalAction)
actionSheet.addAction(highAction)
self.presentViewController(actionSheet, animated: true, completion: nil)
}

How do we create and dismiss an UIAlertController without user input? (Swift)

I've been looking up a lot of tutorials on UIAlertController. Thus far, the way I found was to activate a UIAlertController by linking it to a button or label and then call a IBAction.
I tried to replicate the code to automatically pop an alert when user enters the app (I wanted to ask the user if they want to go through the tutorial). However, I keep getting the error:
Warning: Attempt to present UIAlertController on MainViewController whose view is not in the window hierarchy!
Then I tried to add the UIAlertController to the MainViewController via addChildViewController and addSubview. However, I get the error:
Application tried to present modally an active controller
I figured that I cannot use the presentViewController function and commented it out.
The UIAlertController is displayed BUT when I tried to click on the cancel or the never button, this error occurs.
Trying to dismiss UIAlertController with unknown presenter.
I am really stumped. Can someone share what I am doing wrong? Thank you so much. Here is the code.
func displayTutorial() {
alertController = UIAlertController(title: NSLocalizedString("tutorialAlert", comment: ""), message: NSLocalizedString("tutorialMsg", comment: ""), preferredStyle: .ActionSheet)
self.addChildViewController(alertController)
self.view.addSubview(alertController.view)
alertController.didMoveToParentViewController(self)
alertController.view.frame.origin.x = self.view.frame.midX
alertController.view.frame.origin.y = self.view.frame.midY
//alertController.popoverPresentationController?.sourceView = self.view*/
let OkAction = UIAlertAction(title: NSLocalizedString("yesh", comment: ""), style: .Destructive) { (action) in
}
alertController.addAction(OkAction)
let cancelAction = UIAlertAction(title: NSLocalizedString("notNow", comment: ""), style: .Destructive) { (action) in
//println(action)
self.tutorial = 1
self.presentedViewController?.dismissViewControllerAnimated(true, completion: nil)
}
alertController.addAction(cancelAction)
let neverAction = UIAlertAction(title: NSLocalizedString("never", comment: ""), style: .Cancel) { (action) in
self.tutorial = 1
}
alertController.addAction(neverAction)
//self.presentViewController(alertController, animated: false) {}
}
I found the solution. Apparently, I cannot call the UIAlertController from the func viewDidLoad. I must call the function from viewDidAppear. So my code now is
override func viewDidAppear(animated: Bool) {
if tutorial == 0 {
displayTutorial(self.view)
}
}
func displayTutorial(sender:AnyObject) {
let alertController = UIAlertController(title: NSLocalizedString("tutorialAlert", comment: ""), message: NSLocalizedString("tutorialMsg", comment: ""), preferredStyle: .ActionSheet)
let OkAction = UIAlertAction(title: NSLocalizedString("yesh", comment: ""), style: .Destructive) { (action) in
}
alertController.addAction(OkAction)
let cancelAction = UIAlertAction(title: NSLocalizedString("notNow", comment: ""), style: .Default) { (action) in
//println(action)
self.tutorial = 1
self.presentedViewController?.dismissViewControllerAnimated(true, completion: nil)
}
alertController.addAction(cancelAction)
let neverAction = UIAlertAction(title: NSLocalizedString("never", comment: ""), style: .Cancel) { (action) in
self.tutorial = 1
}
alertController.addAction(neverAction)
self.presentViewController(alertController, animated: true, completion: nil)
if let pop = alertController.popoverPresentationController {
let v = sender as UIView
pop.sourceView = view
pop.sourceRect = v.bounds
}
}
Thanks to this posting: Warning: Attempt to present * on * whose view is not in the window hierarchy - swift
Below UIAlertController with extension would help you show alert with dynamic number of buttons with completion handler for selected index
extension UIViewController {
func displayAlertWith(message:String) {
displayAlertWith(message: message, buttons: ["Dismiss"]) { (index) in
}
}
func displayAlertWith(message:String, buttons:[String], completion:((_ index:Int) -> Void)!) -> Void {
displayAlertWithTitleFromVC(vc: self, title: Bundle.main.infoDictionary!["CFBundleDisplayName"] as! String, andMessage: message, buttons: buttons, completion: completion)
}
func displayAlertWithTitleFromVC(vc:UIViewController, title:String, andMessage message:String, buttons:[String], completion:((_ index:Int) -> Void)!) -> Void {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
for index in 0..<buttons.count {
let action = UIAlertAction(title: buttons[index], style: .default, handler: {
(alert: UIAlertAction!) in
if(completion != nil){
completion(index)
}
})
alertController.addAction(action)
}
DispatchQueue.main.async {
vc.present(alertController, animated: true, completion: nil)
}
}
}
If you need to auto dismiss the alert you can call dismiss on presented view controller after some delay.
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
vc.dismiss(animated: true, completion: nil)
}
Hope this might help you.