2017-06-16 36 views
4

當我關閉導航堆棧中第三個viewController以模態方式呈現的MFMailComposeViewController或MFMessageComposeViewController的實例時,導航堆棧將被重置,並且根VC將被重新加載。我怎樣才能防止這種行爲,並保持原來的呈現viewController(堆棧中的第三個VC)?無論我從提出的VC,提出的VC還是navigationController中調用解僱,我都會得到相同的行爲。如何解除MFMailComposeViewController時導航控制器返回根目錄

這已被問過,但我還沒有看到解決方案。

應用結構如下:

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) 
+1

您需要提供一些實際的代碼,因爲沒有辦法,我們可以知道你做錯了什麼。根據調用者是誰以及該調用者是否提供了某些東西來消除邏輯工作。 – Dima

+0

Dima - 請參閱帶編碼的編輯問題。 – Alpinista

+0

你試過'presentationViewController?.dismiss(self,animated:true)'? – crizzis

回答

0

今天我發現問題與我的導航堆棧。我構建了一個簡單的 項目,它複製了我的問題項目的tabBarController/NavigationControler體系結構,逐個組件,直到解散MFMailComposeViewController導致我的導航堆棧重置,如我的原始文章中所述。

這立即指出了錯誤的來源。在我的子類UINavigationCotroller中,我在代碼中實例化了根viewController,這樣如果用戶在應用程序設置中設置了開關,我就可以跳過介紹性視圖。爲了在該開關設置中選擇更改,我在navigationController的viewDidAppear中調用了我的實例化代碼。這工作得很好,除了解僱mailComposeVC。解決方法是在viewDidAppear中添加一個guard語句,以便在navControllers viewController集合不爲空時返回,並在交換機發生更改時發送並響應NSNotification。

類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() 
} 
1

您也可以使用presentingViewController?.dismiss方法檢查以獲得解決方案。

我已嘗試使用以下導航堆棧。

Navigation Stack

我能夠從容器VC的發送電子郵件按鈕只能用你的代碼成功發送電子郵件。

您可以檢查並驗證導航流程嗎?

如果您仍然面臨任何問題,請讓我知道。

+0

在TripEditorVC中呈現MFMailComposeViewController之後,MFMailComposeViewController的presentsViewController檢查爲零。從相同的TripEditoVC(UIAlertController,SLComposeViewController)呈現的其他模態呈現的視圖控制器報告,根TabBarController是它們的presentsViewController。當我關閉MFMailComposeViewController時,整個堆棧被重新加載。當我關閉其他呈現的viewController時,堆棧不會重新加載,並且應用程序保留在TripEditorVC上。 – Alpinista

+0

如果您使用正確的導航堆棧,那麼它不會是零。請檢查你的控制器是不是從某個地方分配,或者它不是釋放。 –

0

解僱(動畫:真,完成:無)

self.dismiss(動畫:真,完成:無)

試試這個

let storyboard = UIStoryboard(name: "Main", bundle: nil) 
let secondViewController =  storyboard.instantiateViewControllerWithIdentifier("secondViewControllerId") as! SecondViewController 
self.presentViewController(secondViewController, animated: true, completion: nil) 

https://stackoverflow.com/a/37740006/8196100

0

只使用開卷Segue公司其很簡單和完美的,你的情況

我用過很多次..


單看這Unwind segue's example 。如果你仍然無法找到答案,或者無法理解Unwind segue,那就回復我。

希望這會解決您的問題。

相關問題