由于层次结构而无法显示由MFMailComposeViewController创建的页面 - Swift 4

时间:2018-05-28 09:37:32

标签: ios swift uitableview hierarchy mfmailcomposeviewcontroller

我尝试添加一个函数,即在用户触摸表格中的一行后弹出的邮件页面。也就是说,这意味着当点击该行时,用户可以激活“功能”(这里该功能的名称是“orderOfSendAnEmailToReportTheProblem”)。我的所有代码如下所示。 (这种代码已由Stackoverflow上的几个genii提出......)

import Foundation
import UIKit
import MessageUI

class ReportProblem : UIViewController, MFMailComposeViewControllerDelegate {

func orderOfSendAnEmailToReportTheProblem() {
    let mailComposeViewController = configureMailController()
    if MFMailComposeViewController.canSendMail() {
    self.present(mailComposeViewController, animated: true, completion: nil)
    } else {
        showMailError()
    }
}
//Activate the series of the commands of sending the email.


func configureMailController() -> MFMailComposeViewController {
    let mailComposeVC = MFMailComposeViewController()
    mailComposeVC.mailComposeDelegate = self

    mailComposeVC.setToRecipients(["my email"])
    mailComposeVC.setSubject("Yo")

    return mailComposeVC
}
//Set the recipient and the title of this email automatically.

func showMailError() {
    let sendMailErrorAlert = UIAlertController(title: "Could not sned the email.", message: "Oops, something was wrong, please check your internet connection once again.", preferredStyle: .alert)
    let dismiss = UIAlertAction(title: "Ok", style: .default, handler: nil)
    sendMailErrorAlert.addAction(dismiss)
    self.present(sendMailErrorAlert, animated: true, completion: nil) //If you conform the protocol of NSObject instead of UIViewController, you could not finish this line successfully.
}
//Set a alert window so that it would remind the user when the device could not send the email successfully.

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    controller.dismiss(animated: true, completion: nil)
}
//Set this final step so that the device would go to the previous window when you finish sending the email.
}

但是,出现了问题。当我在我的真实设备上测试它,并且在我点击该特定行之后,没有任何事情发生,没有任何新页面弹出...... Xcode只显示“警告:尝试在视图不在窗口层次结构中呈现! “我尝试了几种方法,例如“view.bringSubview(toFront:mailComposeVC)”或在我的代码末尾添加下面显示的代码,但没有任何效果。

func topMostController() -> UIViewController {
    var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
    while (topController.presentedViewController != nil) {
        topController = topController.presentedViewController!
    }
    return topController
}

我注意到其他人在想要创建警报窗口时也会遇到类似的问题,其解决方案是创建一个独立的UIWindow,但我想使用mailComposeController来呈现电子邮件页面。其他一些人也遇到了一些关于MFMailComposeViewController的问题,但他们的问题与层次结构无关。我是一个快速的新手,我被这个问题困扰了一整天...我使用swift 4来开发我的应用程序,有人知道如何在这里解决这个问题吗?...

3 个答案:

答案 0 :(得分:0)

所以现在我正在编写另一种方式来呈现我用于通用视图的方法。 在另一个类中有一些代码用于呈现视图,以便您可以使用这两种方法在整个应用程序中重用它们。

func slideInFromRight(parentView:UIView,childView:UIView) {
    childView.transform = CGAffineTransform(translationX: parentView.frame.maxX, y: 0)
    parentView.addSubview(childView)
    UIView.animate(withDuration: 0.25, animations: {
        childView.transform = CGAffineTransform(translationX: 0, y: 0)
    })
}

func slideOutToRight(view:UIView) {
    UIView.animate(withDuration: 0.25, animations: {
        view.transform = CGAffineTransform(translationX: view.frame.maxX, y: 0)
    },completion:{(completed:Bool) in
        view.removeFromSuperview()
    })
}

现在使用这些方法显示和删除自定义视图控制器,如下所示

let window = UIApplication.shared.keyWindow
let vc = YourViewController().instantiate()
self.addChildViewController(vc)
let view = vc.view

view.frame = CGRect(x: 0, y: 20, width: window!.frame.width, height: window!.frame.height-20)
//Here Animation is my custom presenter class and shared is it's shared instance.

Animation.shared.slideInFromRight(parentView: window!, childView: view)

//Or you can use current View controller's view 
Animation.shared.slideInFromRight(parentView: self.view!, childView: view)

答案 1 :(得分:0)

Genius Vivek Singh,你的方式看起来不错,但有点单调乏味。此外,它仍然无法在我的项目中工作......(您似乎使用了一些关于UIView的代码,例如parentViewchildViewview。但是,我使用了{ {1}}这似乎与原始观点略有不同......我不确定这个理论是否正确......)

但是,我找到了解决方案。我认为问题在于,在用户单击另一个tableViewController中的行(此处为MFMailComposeViewController)之后,它将激活“另一个”viewController中的函数“SettingTVController”(这里是{{ 1}})。因为有两个不同的viewController,发生了某种冲突。

因此,我将我在上述问题中发布的所有代码移动到原来的tableViewController中,这样用户在激活函数时就不会进入另一个viewController,并且不再存在层次结构问题了。

orderOfSendAnEmailToReportTheProblem( )

我在上面发布了我的代码,以便它可以帮助那些有朝一日会遇到类似问题的人。再次感谢您的帮助!!

答案 2 :(得分:0)

我不知道您为什么要面对视图层次结构问题。但是我能够很快实现4的邮件共享选项。我遵循完全相同的步骤。

  1. 检查是否可以发送邮件:

    MFMailComposeViewController.canSendMail()

  2. 配置邮件正文:

    private func configureMailController() -> MFMailComposeViewController {
    let mailComposeViewController = MFMailComposeViewController()
    mailComposeViewController.mailComposeDelegate = self
    mailComposeViewController.setMessageBody("MESSAGE BODY", isHTML: true)
    return mailComposeViewController
    

    }

  3. 当前邮件VC:

    present(mailComposeViewController, animated: true)

  4. 确认可选协议并明确关闭视图:

    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    controller.dismiss(animated: true)
    

    }