如何处理内置的AlertController /电子邮件提示,使其不出现在我的视图后面

问题描述 投票:0回答:1

我的应用程序包含可从任何地方显示的模式UIView。 present方法的工作原理是将视图作为子视图附加到关键窗口上:

func present(_ completion: ((Bool) -> ())? = { _ in }) {

    guard !isPresented else {
        return
    }

    if !isBackgroundReady {
        initializeBackground()
    }

    UIApplication.shared.keyWindow?.addSubview(backgroundView)
    UIApplication.shared.keyWindow?.addSubview(self)

    UIView.animate(withDuration: 0.3, animations: {
        self.backgroundView.alpha = 0.35
        self.alpha = 1.0
    }, completion: { _ in
        self.isPresented = true
        completion?(true)
    })
}

private func initializeBackground() {
    backgroundView.backgroundColor = UIColor.black
    backgroundView.alpha = 0.0
    backgroundView.frame = CGRect(x: UIScreen.main.bounds.midX, y: UIScreen.main.bounds.midY, width: UIScreen.main.bounds.width * 1.2, height: UIScreen.main.bounds.height * 1.2)
    backgroundView.center = CGPoint(x: UIScreen.main.bounds.midX, y: UIScreen.main.bounds.midY)
}

此模式包含一个电子邮件链接,用户可以单击该链接打开一个电子邮件提示(如果长按该链接,则显示电子邮件操作表)。此链接是通过使用NSAttributedString和UITextView上的.link属性添加的:

let supportString = NSMutableAttributedString(
    string: "general.supportEmail".localized(),
    attributes: [
        .link: "mailto:\("general.supportEmail".localized())",
    ]
)
supportTextView.attributedText = supportString

但是,当出现电子邮件提示或操作表时,它显示在模式视图的后面:

app

是否有可能使提示/操作表以当前呈现模态的方式出现在模态视图上方,或者我需要在某种地方添加某种识别器来检测何时出现这些视图之一并暂时关闭该视图。直到我的应用程序视图重新成为焦点?如果是后来的话,我该怎么做?

swift modal-dialog uialertcontroller
1个回答
0
投票

不是在窗口中添加模态,而是在navicontroller中添加模态-> topviewcontroller。

链接:https://developer.apple.com/documentation/uikit/uinavigationcontroller/1621849-topviewcontroller

这可能对您有帮助。


0
投票

关于为什么的快速答案是,您正在窗口的顶部显示自定义模式视图,该视图将显示在所有内容的顶部,并且您的UIAlertController将显示在UIViewController上]展示它(位于您的自定义视图下方)。

一种快速的解决方案是始终将您的自定义视图添加为当前“顶部” UIViewController上的子视图。您可以使用UIViewController扩展名-像这样:

extension UIViewController {

    static func topViewController(_ viewController: UIViewController? = nil) -> UIViewController? {
        let viewController = viewController ?? UIApplication.shared.keyWindow?.rootViewController
        if let navigationController = viewController as? UINavigationController, !navigationController.viewControllers.isEmpty {
            return self.topViewController(navigationController.viewControllers.last)
        } else if let tabBarController = viewController as? UITabBarController,
            let selectedController = tabBarController.selectedViewController
        {
            return self.topViewController(selectedController)
        } else if let presentedController = viewController?.presentedViewController {
            return self.topViewController(presentedController)
        }
        return viewController
    }

}

此扩展名将处理“顶部”的所有UIViewController,无论是在UINavigationControllerUITabBarController中还是仅以模态显示等,都应涵盖所有情况。

之后,您可以调整present方法以考虑到这一点:

func present(_ completion: ((Bool) -> ())? = { _ in }) {
    guard !isPresented else {
        return
    }
    if !isBackgroundReady {
        initializeBackground()
    }
    guard let topViewController = UIViewController.topViewController() else { return }
    topViewController.view.addSubview(backgroundView)
    topViewController.view.addSubview(self)
    UIView.animate(withDuration: 0.3, animations: {
        self.backgroundView.alpha = 0.35
        self.alpha = 1.0
    }, completion: { _ in
        self.isPresented = true
        completion?(true)
    })
}
© www.soinside.com 2019 - 2024. All rights reserved.