在演示过程中尝试在 <a> 上演示 <a>

Attempt to present <a> on <a> while a presentation is in progress

我知道之前有人问过这个问题,但我正在尝试找出我的项目的问题,正如标题所述 (a) 正试图在 (a) 上呈现 我已经检查了所有 segue 触发器以查看是否我不小心设置了一个 segue 以转到它已经打开的同一个视图控制器,但事实并非如此。

查看控制器 1 代码

import UIKit
import UserNotifications

class NotificationViewController: UIViewController {

    let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications

    let current = UNUserNotificationCenter.current()

    @IBAction func Notification(_ sender: Any) {

        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge], completionHandler: {didAllow, error in})

        var i = 0

        while i < 1{

        current.getNotificationSettings(completionHandler: { (settings) in
            if settings.authorizationStatus == .notDetermined {
                // Notification permission has not been asked yet, go for it!
            }

            if settings.authorizationStatus == .denied {
                i = i + 1
                DispatchQueue.main.async {
                    self.performSegue(withIdentifier: "ToLocation", sender: self)
                    // Notification permission was previously denied, go to settings & privacy to re-enable
                }

            }

            if settings.authorizationStatus == .authorized {
                i = i + 1
                DispatchQueue.main.async {
                 self.performSegue(withIdentifier: "ToLocation", sender: self)
                    // Notification permission was already granted
                }

            }
        })
        }

        }

    override func viewDidLoad() {

        current.getNotificationSettings(completionHandler: { (settings) in
            if settings.authorizationStatus == .notDetermined {
                // Notification permission has not been asked yet, go for it!
            }

            if settings.authorizationStatus == .denied {
                DispatchQueue.main.async {
                    self.performSegue(withIdentifier: "ToLocation", sender: self)
                    // Notification permission was previously denied, go to settings & privacy to re-enable
                }

            }

            if settings.authorizationStatus == .authorized {
                DispatchQueue.main.async {
                    self.performSegue(withIdentifier: "ToLocation", sender: self)
                    // Notification permission was already granted
                }

            }
        })

        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

查看控制器 2 代码

    import UIKit
import CoreLocation

class LocationViewController: UIViewController {

    @IBOutlet weak var textview: UITextView!

    let locationManager = CLLocationManager()

    @IBAction func OnLocation(_ sender: Any) {

        locationManager.delegate = self as? CLLocationManagerDelegate

        var i = 0

        while i < 1{

            switch CLLocationManager.authorizationStatus() {
            case .notDetermined:
                // Request when-in-use authorization initially
                locationManager.requestWhenInUseAuthorization()
                break

            case .restricted, .denied:
                i = i + 1
                DispatchQueue.main.async {
                    self.performSegue(withIdentifier: "ToLogin", sender: self)
                }
                // Disable location features
                //disableMyLocationBasedFeatures()
                break

            case .authorizedWhenInUse:
                i = i + 1
                DispatchQueue.main.async {
                    self.performSegue(withIdentifier: "ToLogin", sender: self)
                }
                // Enable basic location features
                //enableMyWhenInUseFeatures()
                break

            case .authorizedAlways:
                // Enable any of your app's location features
               // enableMyAlwaysFeatures()
                break
            }
        }
    }


    override func viewDidLoad() {
        func locationManager(_ manager: CLLocationManager,
                             didChangeAuthorization status: CLAuthorizationStatus) {   switch status {

        case .restricted, .denied:
            self.performSegue(withIdentifier: "ToLogin", sender: self)
            break

        case .authorizedWhenInUse:
            self.performSegue(withIdentifier: "ToLogin", sender: self)
            break

        case .authorizedAlways:
            self.performSegue(withIdentifier: "ToLogin", sender: self)
            break

        case .notDetermined:
            break
            }
        }
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

错误信息

018-02-27 23:06:41.534749+1030 Request[27358:1351259] Warning: Attempt to present on while a presentation is in progress!

你的错误信息很清楚while a presentation is in progress。这意味着您尝试从另一个 LocationViewController 展示 LocationViewController,但它仍然没有展示。

将您的表示逻辑移至 viewWillAppear 方法。会有帮助

更新

1) 将您现有的从通知按钮到 StoryboardLocationViewController 的 segue

2) 添加从 NotificationViewControllerLocationViewController 的 segue,如图所示

3) 为这个 segue 设置名称

现在尝试运行您的项目

不不不不不。这不是办法。很抱歉有很多问题,但是 completionHandler requestAuthorization 的结果参数 来自 UNUserNotification 的方法可以 在后台线程上执行。

此功能的提示

@IBAction func Notification(_ sender: Any) 

*应以小写开头

*提供一个名称,它完成的动作可以通过该名称推断出来

*更改发件人的类型(如果您知道的话),这样您就可以显式调用该对象的属性或方法而无需转换。

继续函数范围内的其余代码。 requestAuthorization 对此负唯一责任 - 请求许可 - 响应是 didAllowerror .你永远不会检查这个并继续启动另一个响应也是另一个线程的块

底线:你在一个循环中调用 requestAuthorization 然后 getNotificationSettings(为什么?),如果这代码执行时间的 30%。

所以你应该把涉及权限的部分代码分开,阅读一些GRASP原则,也阅读每一章here