当我解除从导航堆栈中的第三个viewController以模态方式呈现的MFMailComposeViewController或MFMessageComposeViewController的实例时,将重置导航堆栈,并重新加载根VC。如何防止此行为并保留在原始呈现的viewController(堆栈中的第三个VC)?无论我是从演示VC,演示的VC还是navigationController调用dismiss,我都会得到相同的行为。
以前曾经问过,但我没有看到解决方案。
App Structure看起来像这样:
TabBarController
Tab 1 - TripsNavController
-> Trips IntroductionVC (root VC) segue to:
-> TripsTableViewController segue to:
-> TripEditorContainerVC
- TripEditorVC (child of ContainerVC)
- HelpVC (child of ContainerVC)
Tab 2...
Tab 3...
Tab 4...
在TripEditorVC中,我展示了MFMailComposeViewController。下面的函数在UIViewController的扩展中声明,它采用MFMailComposeViewControllerDelegate协议
func shareWithEmail(message: NSAttributedString) {
guard MFMailComposeViewController.canSendMail() else {
showServiceError(message: "Email Services are not available")
return
}
let composeVC = MFMailComposeViewController()
composeVC.setSubject("My Trip Plan")
composeVC.setMessageBody(getHTMLforAttributedString(attrStr: message), isHTML: true)
composeVC.mailComposeDelegate = self
present(composeVC, animated: true, completion: nil)
}
然后在委托方法中我解雇了MFMailComposeVC:
public func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
switch result {
case .sent:
print("Mail sent")
case .saved:
print("Mail saved")
case .cancelled:
print("Mail cancelled")
case .failed:
print("Send mail failed")
}
if error != nil {
showServiceError(message: "Error: \(error!.localizedDescription)")
}
dismiss(animated: true, completion: nil)
}
我尝试过以下方法来呈现和解散并获得相同的行为,即:TripsNavController清除导航堆栈并重新加载TripsIntroductionVC作为其根VC:
self.present(composeVC, animated: true, completion: nil)
self.parent?.present(composeVC, animated: true, completion: nil)
self.parent?.navigationController?.present(composeVC, animated: true, completion: nil)
self.navigationController?.present(composeVC, animated: true, completion: nil)
答案 0 :(得分:1)
您还可以使用presentingViewController?.dismiss
方法进行检查以获得解决方案。
我尝试过以下导航堆栈。
我可以使用您的代码从Container VC的“发送电子邮件”按钮成功发送电子邮件。
请检查并验证导航流程吗?
如果您仍然遇到任何问题,请告诉我。
答案 1 :(得分:0)
解雇(动画:真实,完成:无)
到
self.dismiss(animated:true,completion:nil)
试试这个
spring.cloud.stream.bindings.toGreeting.contentType=avro/bytes
或
答案 2 :(得分:0)
Just Unwind Segue在您的案例中非常简单和完美
我已多次使用..
看看这个Unwind segue's example 。如果您仍然无法找到答案或无法理解Unwind segue,那么请回复我。
希望这能解决您的问题。
答案 3 :(得分:0)
我今天发现了导航堆栈的问题。我建了一个简单的 项目复制我的问题项目的tabBarController / NavigationControler架构,逐个组件,直到解雇MFMailComposeViewController导致我的导航堆栈重置,如我原来的帖子所述。
这立即指出了bug的来源。在我的子类UINavigationCotroller中,我在代码中实例化了根viewController,这样如果用户在应用程序设置中设置了一个开关,我就可以跳过介绍性视图。为了获取该开关设置中的更改,我在navigationController的viewDidAppear中调用了我的实例化代码。在解雇mailComposeVC时,除了解决方案外,它工作正常。修复是在viewDidAppear中添加一个guard语句,如果navControllers viewController集合不为空则返回,并在交换机发生更改时发送并响应NSNotification。
class TopNavigationController:UINavigationController {
var sectionType: SectionType?
var defaults = UserDefaults.standard
var showIntroFlag: Bool = true
override func viewDidLoad() {
super.viewDidLoad()
// Handle initial load of the tab bar controller where we are not sent a sectionType
if sectionType == nil {
sectionType = .groups
}
setShowIntroFlag()
NotificationCenter.default.addObserver(self, selector: #selector(resetControllers), name: NSNotification.Name(rawValue: "kUserDidChangeShowIntros"), object: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
guard self.viewControllers.isEmpty else {
return
}
loadControllers()
}
func setShowIntroFlag() {
showIntroFlag = true
// Check NSUserDefaults to see if we should hide the Intro Views for all sections
if defaults.bool(forKey: "SHOW_SECTION_INTROS") == false {
showIntroFlag = false
}
}
func loadControllers() {
if showIntroFlag == true {
showIntro()
} else {
skipIntro()
}
}
func resetControllers() {
setShowIntroFlag()
loadControllers()
}