2015-05-27 2 views
1

Я пытаюсь передать selectedName на VC# 2 (BrandTableViewController). Если I println (selectedName) в viewDidDisappear, я получаю значение, однако, значение равно нулю, когда оно находится в prepareForSegue? Может ли кто-нибудь понять, почему?Не удается передать переменную в prepareForSegue в Swift?

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") 
     } 
    } 
+0

Я не вижу каких-либо 'viewDidDisappear' так что трудно понять, о чем вы говорите. – matt

+0

Я удалил его, потому что тест работал, но println (selectedName) в viewDidDisappear возвращает значение (объект Person, выбранный и назначенный в didSelectRow). тот же println в prepareForSegue возвращает nil? – GarySabo

+0

Кстати, возможно, вы не знаете о новом синтаксисе Swift для 'if let'? Он используется как 'if let x = , пусть y = , ..., , ... {...}' – GoZoner

ответ

4

prepareForSegue: метод вызывается перед tableView:didSelectRowAtIndexPath: method.And я видел, что вы только назначить selectedName в методе didSelectRowAtIndexPath .so 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) 
} 
+0

Я думал, что может быть, как я могу обойти его? – GarySabo

+0

Вы можете переместить этот код в 'tableView: willSelectRowAtIndexPath:' – tounaobun

+0

- это вызов, который вызывается перед prepareForSegue? – GarySabo

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] 
     } 
    // ... 
    } 
    } 
+1

спасибо, что обе решения работают – GarySabo

Смежные вопросы