无法将变量传递给Swift中的prepareForSegue?

时间:2015-05-27 01:44:00

标签: ios swift segue

我试图将selectedName传递给VC#2(BrandTableViewController)。如果我在viewDidDisappear中println(selectedName)我得到了值,那么,当它在prepareForSegue中时,值为nil?谁能明白为什么?

import UIKit
import CoreData

class NameTableViewController: UITableViewController, UITableViewDelegate {

    //Changes [String] to [NSManagedObject]
    var people = [NSManagedObject]()

    @IBOutlet var nameTableView: UITableView!

    var selectedName: Person?

    override func viewDidLoad() {
        super.viewDidLoad()
         title = "\"People\""
        nameTableView.delegate = self


        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()

        // Retreive the managedObjectContext from AppDelegate
        let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

        // Print it to the console
        println(managedObjectContext)
    }

   // Mark: - Add Button Alert
    @IBAction func addButton(sender: AnyObject) {
        var alert = UIAlertController(title: "New name",
            message: "Add a new name",
            preferredStyle: .Alert)

        let saveAction = UIAlertAction(title: "Save",
            style: .Default) { (action: UIAlertAction!) -> Void in

                let textField = alert.textFields![0] as! UITextField
                self.saveName(textField.text)
                self.tableView.reloadData()
        }

        let cancelAction = UIAlertAction(title: "Cancel",
            style: .Default) { (action: UIAlertAction!) -> Void in
        }

        alert.addTextFieldWithConfigurationHandler {
            (textField: UITextField!) -> Void in
        }

        alert.addAction(saveAction)
        alert.addAction(cancelAction)

        presentViewController(alert,
            animated: true,
            completion: nil)
    }

    //function to save a name (code from: http://www.raywenderlich.com/85578/first-core-data-app-using-swift)
    func saveName(name: String) {
        //1
        let appDelegate =
        UIApplication.sharedApplication().delegate as! AppDelegate

        let managedContext = appDelegate.managedObjectContext!

        //2
        let entity =  NSEntityDescription.entityForName("Person",
            inManagedObjectContext:
            managedContext)

        let person = NSManagedObject(entity: entity!,
            insertIntoManagedObjectContext:managedContext)

        //3
        person.setValue(name, forKey: "name")

        //4
        var error: NSError?
        if !managedContext.save(&error) {
            println("Could not save \(error), \(error?.userInfo)")
        }  
        //5
        people.append(person)
    }



    // MARK: - Table view data source

//    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
//        // #warning Potentially incomplete method implementation.
//        // Return the number of sections.
//        return 1
//    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete method implementation.
        // Return the number of rows in the section.
        return people.count

    }

    private struct Storyboard {
        static let CellReuseIdentifier = "Name"
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(Storyboard.CellReuseIdentifier, forIndexPath: indexPath) as! UITableViewCell


        let person = people[indexPath.row]
        cell.textLabel!.text = person.valueForKey("name") as? String

        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let row = self.tableView.indexPathForSelectedRow()!.row
        println("row \(row) was selected")
         selectedName = people[indexPath.row] as? Person
        println(selectedName)
//        if let unWrappedSelectedName = selectedName {
// //       println(unWrappedSelectedName)
//        }
//        else {
//            println("no person was selected in didSelectRowAtIndexPath")
//        }
    }


    // Override to support conditional editing of the table view.
    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return NO if you do not want the specified item to be editable.
        return true
    }



    // Override to support editing the table view.
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            let personToDelete = people[indexPath.row]

            //abstract this into helper function later
            let appDelegate =
            UIApplication.sharedApplication().delegate as! AppDelegate
            let managedContext = appDelegate.managedObjectContext!
            managedContext.deleteObject(personToDelete)
            self.fetchCoreData()

            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }




    /*
    // Override to support rearranging the table view.
    override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {

    }
    */

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return NO if you do not want the item to be re-orderable.
        return true
    }
    */


    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        fetchCoreData()

    }


    //Helper Function to Fetch Core Data
    func fetchCoreData() {
        //1
        let appDelegate =
        UIApplication.sharedApplication().delegate as! AppDelegate

        let managedContext = appDelegate.managedObjectContext!

        //2
        let fetchRequest = NSFetchRequest(entityName:"Person")

        //3
        var error: NSError?

        let fetchedResults = managedContext.executeFetchRequest(fetchRequest,
            error: &error) as? [NSManagedObject]

        if let results = fetchedResults {
            people = results
        } else {
            println("Could not fetch \(error), \(error!.userInfo)")
        }
    }

    // MARK: - Navigation


    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
                if let btvc = segue.destinationViewController as? BrandsTableTableViewController {
                    if let identifer = segue.identifier {
                        if identifer == "segueToBrands" {
                          btvc.selectedName = selectedName
                            println(selectedName)
                        }
                    }
                }
                else {
                    println("we have a segue problem")
        }
    }

2 个答案:

答案 0 :(得分:4)

prepareForSegue:方法之前调用tableView:didSelectRowAtIndexPath:方法。我看到您只在方法selectedName中指定didSelectRowAtIndexPath。所以selectedName将始终为零在prepareForSegue

您可以在selectedName

中指定tableView:willSelectRowAtIndexPath:
override func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) {
    let row = self.tableView.indexPathForSelectedRow()!.row
    println("row \(row) was selected")
     selectedName = people[indexPath.row] as? Person
    println(selectedName)
}

答案 1 :(得分:1)

preprareForSegue()中,您可以访问所选的单元格(或单元格):

  override func prepareForSegue (segue: UIStoryboardSegue, sender: AnyObject?) {
    switch segue.identifier ?? "" {
    case "theSegue":
      if let indexPath = tableView.indexPathForSelectedRow () {
        // get what you need from the cell or the DataSource object
        let controller = segue.destinationViewController as! PersonController
        controller.person = people[indexPath.row]
      }
    // ...
    }
  }