-1

I'm building a chart that has bars with onTap that calls a function to display totals. The function has the below code but doesn't like the alert present, "Use of unresolved identifier "present" error appears.

At the top of my code I have import UIKit and my function is as below:

func displayTotals(monthSelected: Int, monthTotalQty: Int, monthTotalCurrency: Int){
    let alert = UIAlertController(title: "\(monthSelected) Totals", message: "Quantity \(monthTotal) | Total \(monthTotalCurrency)", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "Ok", style: .destructive) { _ in
        return
    })
    present(alert, animated: true)
}
  • Where is that code? What object calls it? Only a UIViewController can call `present(_:animated:completion:)` – Larme Oct 21 '19 at 10:39
  • My chart is a View object on my VC that I've connected to a Custom Class where the above code is placed. In the VC I have an outlet: class ByMonthVC: UIViewController { @IBOutlet weak var TObyMonthChart: ChartTObyMonth! – Sebastien Desemberg Oct 21 '19 at 10:45

1 Answers1

0

Seem that your are calling this method outside a UIViewController. In this case you can add the view controller as a parameter of your func.

func displayTotals(rootVC: UIViewController,  monthTotal: Int,  monthSelected: Int, monthTotalQty: Int, monthTotalCurrency: Int){
        let alert = UIAlertController(title: "\(monthSelected) Totals", message: "Quantity \(monthTotal) | Total \(monthTotalCurrency)", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Ok", style: .destructive) { _ in
            return
        })
        rootVC.present(alert, animated: true)
    }

alternatively you can get the root ViewController statically, without changing le sign of your func:

   func displayTotals( monthTotal: Int,  monthSelected: Int, monthTotalQty: Int, monthTotalCurrency: Int){
            let alert = UIAlertController(title: "\(monthSelected) Totals", message: "Quantity \(monthTotal) | Total \(monthTotalCurrency)", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Ok", style: .destructive) { _ in
                return
            })
  var rootVC = UIApplication.shared.keyWindow?.rootViewController
  rootVC?.present(alert, animated: true)
        }
christian mini
  • 1,662
  • 20
  • 39
  • Ok that makes sense, I need to do a step back to call it. What would the first parameter of the function call be? _ = bar.onTap { _ in displayTotals(ByMonthVC: nil, monthSelected: i, monthTotalQty: dataSelectedYearTotal[i], monthTotalCurrency: dataSelectedYearQty[i])} – Sebastien Desemberg Oct 21 '19 at 10:58
  • Option 2 compiles when I add a ! after rootVC but I get an output error: 2019-10-21 13:10:17.325416+0200 Mobile_Application[3522:950497] Warning: Attempt to present on whose view is not in the window hierarchy! – Sebastien Desemberg Oct 21 '19 at 11:11
  • 1
    Use a closure/delegate between VC & View instead. Also, the `rootViewController` might be "outdated". – Larme Oct 21 '19 at 12:01
  • Thanks for the feedback, your answer and this thread helped. https://stackoverflow.com/questions/54209766/swift-4-attempt-to-present-viewcontroller-whose-view-is-not-in-the-window-hierar – Sebastien Desemberg Oct 22 '19 at 08:17