Home > front end >  How to pass the data from ViewController to UITableViewController using TabBarController (without se
How to pass the data from ViewController to UITableViewController using TabBarController (without se

Time:11-05

I have a ViewController that has a UIBarButtonItem on it, I need the data from the TextField (textField  is in the ViewController) to be passed to the TableViewController when the button is clicked without switching to it (TableViewController). ViewController and TableController are associated with TabBarController. ViewController have NavigationController. My version of the code does not work. By clicking on the button, the data is not saved. And in the TableViewController there is only one empty cell.

Image: enter image description here

The CallViewController has two text fields (because you haven't indicated how you are loading a "Contact image"), a "message label", and the "Save" button up in the nav bar.

We start with the Contact struct - I'll use two strings:

struct Contact {
    var title: String
    var imageName: String
}

Now we'll create a Singleton data manager class:

class MyContactData {
    var myContacts: [Contact] = []
    
    static let shared: MyContactData = {
        let instance = MyContactData()
        // setup code
        return instance
    }()
}

In the Call view controller, when we tap the Save button:

class CallViewController: UIViewController, UITextFieldDelegate {
    
    @IBOutlet var nameTextField: UITextField!
    @IBOutlet var imageTextField: UITextField!

    @IBOutlet var msgLabel: UILabel!

    func textFieldDidBeginEditing(_ textField: UITextField) {
        msgLabel.text = ""
    }
    
    @IBAction func saveContact(_ sender: UIBarButtonItem) {
        print("save")
        
        view.endEditing(true)

        let title = nameTextField.text ?? "Unknown"
        let imgName = imageTextField.text ?? "Unknown"
        
        // create a Contact
        let c = Contact(title: title, imageName: imgName)
        
        // append it to shared data in the data manager singleton
        MyContactData.shared.myContacts.append(c)
        
        // show that we "saved" the data
        msgLabel.text = "Saved:\n\(title)\n\(imgName)"

        // clear the text fields
        nameTextField.text = ""
        imageTextField.text = ""
    }
    
}

and, finally, our History table view controller will look like this:

class HistroyCallsTableViewController: UITableViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        tableView.reloadData()
    }
    
    // MARK: - Table view data source
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // our data is in our shared data manager class
        return MyContactData.shared.myContacts.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? ContactTableViewCell {
            
        // our data is in our shared data manager class
            let title = MyContactData.shared.myContacts[indexPath.row].title
            let imgName = MyContactData.shared.myContacts[indexPath.row].imageName
            
            cell.titleContactLabel.text = title
            
            // try to load the image as named asset
            if let img = UIImage(named: imgName) {
                cell.contactPhotoimaveView.image = img
            } else {
                // try to load it as a system image
                if let img = UIImage(systemName: imgName) {
                    cell.contactPhotoimaveView.image = img
                } else {
                    // no image available, so let's use the row number
                    //  as an SF Symbol "indice"
                    if let img = UIImage(systemName: "\(indexPath.row).circle") {
                        cell.contactPhotoimaveView.image = img
                    }
                    
                }
            }

            return cell
        }
        return UITableViewCell()
    }
}

class ContactTableViewCell: UITableViewCell {
    
    @IBOutlet var titleContactLabel: UILabel!
    @IBOutlet var contactPhotoimaveView: UIImageView!
    
}

When we run the app, we'll enter "Bob" and "car":

enter image description here

Tap "Save" and we see this:

enter image description here

Enter "Joe" and "sailboat" ... tap Save:

enter image description here

Tap the Tab icon for History:

enter image description here

Now, most likely, you will want to save -- persist -- the data between app uses? In that case, instead of using the simple MyContactData singleton class as shown, you would use something like Core Data ... but the process would be the same:

  • allow user to enter data
  • on Save tap, save the data via Core Data
  • on navigating to the table view controller, populate it from Core Data
  • Related