Tengo una aplicación que muestra documentos en un UICollectionView. Cada UICollectionViewCell tiene un botón (distinto del realizado por didSelectItemAt). Este botón muestra una ventana emergente personalizada que he creado usando un UIViewController. Se presenta Over Current Context. Esta ventana emergente presenta una lista de opciones, una que incluye Delete document. Cuando un usuario selecciona esta última opción, me gustaría que aparezca un UIAlertController para confirmar la eliminación. Este es el problema que estoy enfrentando.

Aquí está mi código:

El error que estoy recibiendo es:

Finalización de la aplicación debido a la excepción no detectada 'NSInvalidArgumentException', razón: 'La aplicación intentó presentar modalmente un controlador activo.

POPUP PERSONALIZADO (UIViewController)

protocol DismissOptionShowDeleteAlert {
    func showDeleteAlert()
}

class MoreOptionsOnPDFViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{

var showDeleteAlertDelegate: DismissOptionShowDeleteAlert!

/ TAP ON ROW
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){

    ...

     }else if indexPath == [0,4]{ // DELETE DOCUMENT

        DispatchQueue.main.async {
            self.dismiss(animated: true) {
                self.showDeleteAlertDelegate.showDeleteAlert()
            }
        }
    }

    ...

}

UICollectionView:

class CollectionViewFolder: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate ,UICollectionViewDelegateFlowLayout, MoreInfoDocument, MoveFolder, ScanObjectMovedFolder, DismissOptionShowDeleteAlert{

// SHOW DELETE CONFIRMATION ALERT
func showDeleteAlert() {

    Alerts.deleteDocumentConfirm(on: self) {
        // DELETE DOCUMENT FROM SERVER
        print("Delete document ...")
    }
}

}

Estructura UIAlertController:

import Foundation
import UIKit

struct Alerts {
private static func showBasicAlert(on vc: UIViewController, with title: String, message: String, action: @escaping (() -> ())){

    let alert =  UIAlertController.init(title: title, message: message, preferredStyle: .alert)
    let okAction = UIAlertAction.init(title: "OK", style: .default) { (UIActionAlert) in

        action()
    }

    let cancelAction = UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil)

    alert.addAction(okAction)
    alert.addAction(cancelAction)
    DispatchQueue.main.async {
        vc.present(vc, animated: true, completion: nil)
    }

}


static func deleteDocumentConfirm(on vc: UIViewController, action: @escaping (() -> ())){
    showBasicAlert(on: vc, with: "Please Confirm Delete", message: "", action: action)
}

}    
-3
dean 10 sep. 2018 a las 12:25

3 respuestas

La mejor respuesta

Es exactamente lo que dice tu error. Parece que está presentando el controlador de vista vc en lugar del alert de vc

private static func showBasicAlert(on vc: UIViewController, with title: String, message: String, action: @escaping (() -> ())){

    let alert =  UIAlertController.init(title: title, message: message, preferredStyle: .alert)
    let okAction = UIAlertAction.init(title: "OK", style: .default) { (UIActionAlert) in

        action()
    }

    let cancelAction = UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil)

    alert.addAction(okAction)
    alert.addAction(cancelAction)
    DispatchQueue.main.async {
        vc.present(alert, animated: true, completion: nil) // You should be presenting the alert here.
    }

}
2
Rakesha Shastri 10 sep. 2018 a las 09:33

Estás presentando mal. Necesita presentar alerta no vc.

Reemplace a continuación con su código.

struct Alerts {
private static func showBasicAlert(on vc: UIViewController, with title: String, message: String, action: @escaping (() -> ())){

    let alert =  UIAlertController.init(title: title, message: message, preferredStyle: .alert)
    let okAction = UIAlertAction.init(title: "OK", style: .default) { (UIActionAlert) in

        action()
    }

    let cancelAction = UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil)

    alert.addAction(okAction)
    alert.addAction(cancelAction)
    DispatchQueue.main.async {
        vc.present(alert, animated: true, completion: nil)
    }

}
1
Denis 10 sep. 2018 a las 09:31

Reemplazar debajo de la línea

vc.present(vc, animated: true, completion: nil)

Para

vc.present(alert, animated: true, completion: nil)

1
Pankil 10 sep. 2018 a las 09:32