Swift - self.navigationController becomes nil after navigating

I am experiencing a very strange error in my application, between two views, self.navigationController

it becomesnil

I have multiple view controllers: MainViewController

, SecondViewController

PastSessionsViewController

, JournalViewController

. I use it JournalViewController

for two purposes, to save a new record in CoreData or edit an older one. The details are irrelevant to this error.

The error occurs when I try to pop JournalViewController

from the stack and return to MainViewController

, but only when JournalViewController

in edit mode, not when it "saves the new write mode"

Any idea 1) why this is happening and 2) how to properly access it so that I can return to PastSessionsViewController

when returning from JournalViewController

in edit mode?

Here's some code to make things specific.

In AppDelegate.swift

(inside didFinishLaunchingWithOptions

):

navController = UINavigationController()

navController!.navigationBarHidden = true
var viewController = MainViewController()
navController!.pushViewController(viewController, animated: false)

window = UIWindow(frame: UIScreen.mainScreen().bounds)
window?.backgroundColor = UIColor.whiteColor()
window?.rootViewController = navController
window?.makeKeyAndVisible()

      

In MainViewController

:

func goToPastSessions(sender: UIButton) {
    let pastSessionsVC = PastSessionsViewController()
    self.navigationController?.pushViewController(pastSessionsVC, animated: true)
}

func goToWriteJournalEntry(sender: UIButton) {
    let journalVC = JournalViewController(label: "Record your thoughts")
    self.navigationController?.pushViewController(journalVC, animated: true)
}

      

In PastSessionsViewController

:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let editJournalVC = JournalViewController(label: "Edit your thoughts")

    let indexPath = tableView.indexPathForSelectedRow()
    let location = indexPath?.row
    let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! EntryCell

    if let objects = pastSessionsDataSource.coreDataReturn {
        if let location = location {
            editJournalVC.journalEntryCoreDataLocation = location
            editJournalVC.editEntry = true
            editJournalVC.journalEntryToEdit = objects[location].journalEntry
        }
    }

    self.navigationController?.presentViewController(editJournalVC, animated: true, completion: nil)
}

      

Finally, in JournalViewController

:

func doneJournalEntry(sender: UIButton) {
    journalEntryTextArea?.resignFirstResponder()
    var entry = journalEntryTextArea?.text

    if let entry = entry {
        let appDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
        let managedObjectContext = appDelegate.managedObjectContext!
        let request = NSFetchRequest(entityName: "Session")
        var error: NSError?

        // new entry
        if journalEntryText == "Record your thoughts" {
            let result = managedObjectContext.executeFetchRequest(request, error: &error)

            if let objects = result as? [Session] {
                if let lastTime = objects.last {
                    lastTime.journalEntry = entry
                }
            }
        } else {
            // existing entry
            let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
            request.sortDescriptors = [sortDescriptor]

            let result = managedObjectContext.executeFetchRequest(request, error: &error)
            if let objects = result as? [Session] {
                var location = journalEntryCoreDataLocation

                var object = objects[location!]
                object.journalEntry = entry
            }
        }

        if !managedObjectContext.save(&error) {
            println("save failed: \(error?.localizedDescription)")
        }
    }

   // in "edit" mode, self.navigationController is `nil` and this fails
   // in "record a new entry" mode, it not nil and works fine
    self.navigationController?.popViewControllerAnimated(true)
}

func cancelEntryOrEditAndReturn(sender: UIButton) {
    self.journalEntryTextArea?.resignFirstResponder()

   // in "edit" mode, self.navigationController is `nil` and this fails
   // in "record a new entry" mode, it not nil and works fine
    self.navigationController?.popViewControllerAnimated(true)
}

      

Thanks for watching

+3


source to share


1 answer


You have to click editJournalVC instead of the view if you want it to be on the same navigation stack. Because when you present a controller, it is no longer on the same navigation stack. Also, if you present it, you must reject it not pop. Therefore, if you want to expose a controller, you must use

self.dismissViewControllerAnimated(true, completion: nil)

      



instead

self.navigationController?.popViewControllerAnimated(true)

      

+6


source







All Articles