从viewcontroller tableview传递数据到另一个视图控制器

问题描述:

我有一个从表视图控制器传递数据到另一个视图控制器的问题。我试图将用户的名字传递给另一个视图控制器。到目前为止,核心数据通过存储用户名和删除单元格中的人员姓名来工作,但是当我从列表中选择一个用户时,它不会将我带到下一个视图控制器。从viewcontroller tableview传递数据到另一个视图控制器

class tableViewController: UITableViewController { 

@IBOutlet weak var tableview: UITableView! 

//Properties 
var people: [NSManagedObject] = [] 

override func viewDidLoad() { 
    super.viewDidLoad() 

    title = "The List" 
    tableview.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") 
    // Do any additional setup after loading the view, typically from a nib. 
} 
//Fetching data from the core data 
override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 

    //1. Before requesting to coredata, it needs a managed object context. 
    guard let appDelegate = 
     UIApplication.shared.delegate as? AppDelegate else { 
      return 
    } 

    let managedContext = 
     appDelegate.persistentContainer.viewContext 

    //2. Using NSFetchRequest class to fetch core data. Fetching all obejcts within an entity (Person). 
    let fetchRequest = 
     NSFetchRequest<NSManagedObject>(entityName: "Person") 

    //3. Putting in the fetch request to the managed object context, to get fetch data. 
    do { 
     people = try managedContext.fetch(fetchRequest) 
    } catch let error as NSError { 
     print("Could not fetch. \(error), \(error.userInfo)") 
    } 
} 
//Adding the person's name into the table view when the clicks on the add button and enter in their name. 
@IBAction func addName(_ sender: UIBarButtonItem) { 
    let alert = UIAlertController(title: "New Name", 
            message: "Add a new name", 
            preferredStyle: .alert) 

    let saveAction = UIAlertAction(title: "Save", style: .default) { 
     [unowned self] action in 

     guard let textField = alert.textFields?.first, 
      let nameToSave = textField.text else { 
       return 
     } 

     self.save(name: nameToSave) 
     self.tableview.reloadData() 
    } 

    let cancelAction = UIAlertAction(title: "Cancel", 
            style: .default) 

    alert.addTextField() 

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

    present(alert, animated: true) 
} 

// Where the coredata is stored. 
func save(name: String) { 

guard let appDelegate = 
    UIApplication.shared.delegate as? AppDelegate else { 
     return 
} 

//1.Before saving or retrieving from core data, NSManagedObjectContext is to be implemented. Managed context is considered s in-memory to working with managed object context. 
let managedContext = 
    appDelegate.persistentContainer.viewContext 

//2. Creating new managed object and inserting it into managed object context. NSEntityDescrption links he entity definitionfrom data model with an instance of NSanagedObject at runtime. 
let entity = 
    NSEntityDescription.entity(forEntityName: "Person", 
           in: managedContext)! 

let person = NSManagedObject(entity: entity, 
          insertInto: managedContext) 

//3. The "name" attribute is set using the key value coding. KVC key (name) should be spelt as diplayed in data model else app could crash at run time. 
person.setValue(name, forKeyPath: "name") 

//4. Changed are saved to the disk using the managed object context. Save could bring an error which is why try is used within do and catch block. The new managed object is inserted into the "people" array, so it appears when table view is reloaded. 
do { 
    try managedContext.save() 
    people.append(person) 
} catch let error as NSError { 
    print("Could not save. \(error), \(error.userInfo)") 
} 
} 
} 

// MARK: - UITableViewDataSource 
extension tableViewController: UITableViewDataSource { 
override func tableView(_ tableView: UITableView, 
       numberOfRowsInSection section: Int) -> Int { 
    return people.count 
} 

override func tableView(_ tableView: UITableView, 
       cellForRowAt indexPath: IndexPath) 
    -> UITableViewCell { 

     let person = people[indexPath.row] 
     let cell = 
      tableView.dequeueReusableCell(withIdentifier: "Cell", 
              for: indexPath) 
     cell.textLabel?.text = 
      person.value(forKeyPath: "name") as? String 
     return cell 
} 

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
    if editingStyle == .delete { 
     //print("Deleted") 

     //short-cut to access App Delegate 
     let ad = UIApplication.shared.delegate as! AppDelegate 
     let context = ad.persistentContainer.viewContext 
     ad.saveContext() 

     context.delete(people[indexPath.row]) 
     people.remove(at: indexPath.row) 
     tableView.reloadData() 
    } 
} 
// MARK: - Navigation 

// In a storyboard-based application, you will often want to do a little preparation before navigation 
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 

} 

}

+0

相关代码部分在哪里? –

所以,你想从你的tableview选择它们后,通过选择下一个视图控制器的人吗?

首先为您选择的人声明一个类变量。

var selectedPerson: NSManagedObject? 

然后,你需要实现的功能

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    selectedPerson = people[indexPath.row] 
    self.performSegue(withIdentifier: "showPerson", sender: nil) 
} 

之后,修改当前的功能,这

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if segue.identifier == "showPerson" { 
     if let personController = segue.destination as? YOURPERSONCONTROLLERCLASS { 
      personController.person = selectedPerson 
     } 
    } 
} 

你必须YOURPERSONCONTROLLERCLASS改变到ViewController类和类也需要一个NSManagedObject类型的变量。

+0

非常感谢您的帮助,它的工作:) – Harry

+0

如果您的要求,请点击我答案左侧的勾号图标接受它。谢谢 – Devster101