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

Posted

技术标签:

【中文标题】将数据从 viewcontroller tableview 传递到另一个视图控制器【英文标题】:Pass data from viewcontroller tableview to another view controller 【发布时间】:2017-04-12 09:33:03 【问题描述】:

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

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?) 


【问题讨论】:

相关代码部分在哪里? 【参考方案1】:

所以你想在从你的 tableview 中选择他们之后将选择的人传递给下一个 ViewController?

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

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 类型的变量 person。

【讨论】:

如果您正在寻找它,请单击我的答案左侧的勾号图标以接受它。谢谢

以上是关于将数据从 viewcontroller tableview 传递到另一个视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据从模态 ViewController 传输到父 ViewController?

通过 segue 将 CKAsset 图像传递给 ViewController?

将数据从 ViewController 传递回根 ViewController?

使用 Table 加载 UIView 时无法从其 dataSource 中获取单元格

将数据从 UITableViewCell 传递到 ViewController

将数据从 ViewController 转发到 ContainerView