Reputation: 227
I been trying to get my head around passing data to various view controllers over the last few days. I jumped in a bit too too deep at the start and got very confused. Finally I think I have sorted. However I cannot see where I have gone wrong below. I am close but think i have gone blind from trying so much over the weekend. Looked at callbacks but I think delegates make more sense to me.
I have 2 view controllers. One with a UITableView and one where the data get inputted via text field. I have no errors. However the input prints in viewcontroller 2 but does not show up in the UITableView. Finding it hard to see what I've done wrong.
VC1:
import Foundation
import UIKit
private let reuseidentifier = "Cell"
//here
struct Contact {
var fullname: String
}
class ContactController: UITableViewController {
var contacts = [Contact]()
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationItem.title = "Contacts"
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(handleAddContact))
view.backgroundColor = .white
tableView.register(UITableViewCell.self, forCellReuseIdentifier: reuseidentifier)
}
@objc func handleAddContact () {
//here
let controller = AddContactController()
controller.delegate = self
self.present(UINavigationController(rootViewController: controller), animated: true, completion: nil)
}
//UITABLEVIEW
override func numberOfSections(in tableView: UITableView) -> Int {
return contacts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseidentifier, for: indexPath)
cell.textLabel?.text = contacts[indexPath.row].fullname
return cell
}
}
//here
extension ContactController: AddContactDelegate {
func addContact(contact: Contact) {
self.dismiss(animated: true) {
self.contacts.append(contact)
self.tableView.reloadData()
}
}
}
My VC2 where data gets inputted
import Foundation
import UIKit
//here
protocol AddContactDelegate {
func addContact(contact: Contact)
}
class AddContactController: UIViewController {
//here
var delegate: AddContactDelegate?
let textField: UITextField = {
let tf = UITextField()
tf.placeholder = "Full Name"
tf.textAlignment = .center
tf.translatesAutoresizingMaskIntoConstraints = false
return tf
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleDone))
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(handleCancel))
view.addSubview(textField)
textField.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
textField.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
textField.widthAnchor.constraint(equalToConstant: view.frame.width - 64).isActive = true
textField.becomeFirstResponder()
}
//here
@objc func handleDone(){
print("done")
guard let fullname = textField.text, textField.hasText else {
print("handle error here")
return
}
let contact = Contact(fullname: fullname)
delegate?.addContact(contact: contact)
print(contact.fullname)
}
@objc func handleCancel(){
self.dismiss(animated: true, completion: nil )
}
}
Upvotes: 0
Views: 47
Reputation: 100503
There is no problem with your delegate implementation , You need to implement numberOfRowsInSection
and return 1
override func numberOfSections(in tableView: UITableView) -> Int {
return contacts.count
}
override func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return 1
}
Or think if you really need this only
override func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return contacts.count
}
Upvotes: 1
Reputation: 1091
I believe protocol is implemented properly. Only thing I see is you are adding contacts after vc2 is dismissed as part of completion handler. Place the code before calling dismiss:
In func addContact()
contacts.append(contact)
tableView.reloadData()
dismiss()
Upvotes: 0