I am trying to pass data BACK to the previous viewController using delegates.
Does anyone know how to pass data back from ViewController B to ViewController A?
So I want to pass data from SecondVC to FirstVC and update custom table view cells with the data from SecondVC 4 address text fields but for some reason, it's not updating at all.
Any help will be much appreciated as I'm just at the beginning level so tried all sorts of things but not able to get it to work.
FirstVC
import UIKit
class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource, DataSentDelegate {
@IBOutlet weak var deliveryAddress: UITableView!
var customCell: AddressCell = AddressCell()
override func viewDidLoad() {
super.viewDidLoad()
deliveryAddress.delegate = self
deliveryAddress.dataSource = self
deliveryAddress.reloadData()
}
func userDidEnterData(firstAddress: String, secondAddress: String, cityAddress: String, postcodeAddress: String) {
customCell.firstLineAddressLbl?.text = firstAddress
customCell.secondLineAddressLbl?.text = secondAddress
customCell.cityLineAddressLbl?.text = cityAddress
customCell.postcodeLineAddressLbl?.text = postcodeAddress
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "deliveryAddressCell", for: indexPath) as! AddressCell
cell.updateUI()
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 165
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "addDeliveryAddressVC" {
let addDestination:AddingDestinationVC = segue.destination as! AddingDestinationVC
addDestination.delegate = self
}
}
}
SecondVC
import UIKit
protocol DataSentDelegate {
func userDidEnterData(firstAddress: String, secondAddress: String, cityAddress: String, postcodeAddress: String)
}
class AddingDestinationVC: UIViewController {
@IBOutlet weak var firstLineAddressTextField: UITextField!
@IBOutlet weak var secondLineAddressTextField: UITextField!
@IBOutlet weak var cityLineAddressTextField: UITextField!
@IBOutlet weak var postcodeLineAddressTextField: UITextField!
var delegate: DataSentDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func addBtnWasPressed(_ sender: Any) {
if delegate != nil {
if firstLineAddressTextField.text != nil {
let firstLineAddress = firstLineAddressTextField.text
print(firstLineAddress as Any)
let secondLineAddress = secondLineAddressTextField.text
let cityLineAddress = secondLineAddressTextField.text
let postcodeLineAddress = postcodeLineAddressTextField.text
delegate?.userDidEnterData(firstAddress: firstLineAddress!, secondAddress: secondLineAddress!, cityAddress: cityLineAddress!, postcodeAddress: postcodeLineAddress!)
navigationController?.popViewController(animated: true)
}
}
}
}
CustomCell
import UIKit
class AddressCell: UITableViewCell {
@IBOutlet weak var firstLineAddressLbl: UILabel!
@IBOutlet weak var secondLineAddressLbl: UILabel!
@IBOutlet weak var cityLineAddressLbl: UILabel!
@IBOutlet weak var postcodeLineAddressLbl: UILabel!
@IBOutlet weak var numberLbl: UILabel!
@IBOutlet weak var startBtn: UIButton!
@IBOutlet weak var distanceLbl: UILabel!
@IBOutlet weak var metricLbl: UILabel!
func updateUI() {
DeliveryDestinations(FirstLineAddress: firstLineAddressLbl.text, SecondLineAddress: secondLineAddressLbl.text, CityLineAddress: cityLineAddressLbl.text, PostCodeLineAddress: postcodeLineAddressLbl.text)
}
}
Model file
import Foundation
struct DeliveryDestinations {
var FirstLineAddress: String?
var SecondLineAddress: String?
var CityLineAddress: String?
var PostcodeLineAddress: String?
init(FirstLineAddress: String? , SecondLineAddress: String?, CityLineAddress: String?, PostCodeLineAddress: String?) {
self.FirstLineAddress = FirstLineAddress
self.SecondLineAddress = SecondLineAddress
self.CityLineAddress = CityLineAddress
self.PostcodeLineAddress = PostCodeLineAddress
}
}
Check below corrected code:
MainVC:
import UIKit
class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource, DataSentDelegate {
@IBOutlet weak var deliveryAddress: UITableView!
//Create array which will return your address data
var addressArr = [DeliveryDestinations]()
override func viewDidLoad() {
super.viewDidLoad()
deliveryAddress.delegate = self
deliveryAddress.dataSource = self
deliveryAddress.reloadData()
}
//add parameter for created address object
func userDidEnterData(addressObj: DeliveryDestinations) {
//append added object into your table array
self.addressArr.append(addressObj)
//Reload your tableview once your new object added.
self.deliveryAddress.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//change this with array count
return addressArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "deliveryAddressCell", for: indexPath) as! AddressCell
//get address object from array which you can assign to cell
let addressObj = addressArr[indexPath.row]
//assign data from array
cell.updateUI(addressObj: addressObj)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 165
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "addDeliveryAddressVC" {
let addDestination:AddingDestinationVC = segue.destination as! AddingDestinationVC
addDestination.delegate = self
}
}
}
AddingDestinationVC:
import UIKit
protocol DataSentDelegate {
//Replace parameter with DeliveryDestinations
func userDidEnterData(addressObj: DeliveryDestinations)
}
class AddingDestinationVC: UIViewController {
@IBOutlet weak var firstLineAddressTextField: UITextField!
@IBOutlet weak var secondLineAddressTextField: UITextField!
@IBOutlet weak var cityLineAddressTextField: UITextField!
@IBOutlet weak var postcodeLineAddressTextField: UITextField!
var delegate: DataSentDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func addBtnWasPressed(_ sender: Any) {
if delegate != nil {
if firstLineAddressTextField.text != nil {
//Create Model object DeliveryDestinations
let addressObj = DeliveryDestinations(FirstLineAddress: firstLineAddressTextField.text, SecondLineAddress: secondLineAddressTextField.text, CityLineAddress: cityLineAddressTextField.text, PostCodeLineAddress: postcodeLineAddressTextField.text)
//add that object to previous view with delegate
delegate?.userDidEnterData(addressObj: addressObj)
navigationController?.popViewController(animated: true)
}
}
}
}
AddressCell:
class AddressCell: UITableViewCell {
@IBOutlet weak var firstLineAddressLbl: UILabel!
@IBOutlet weak var secondLineAddressLbl: UILabel!
@IBOutlet weak var cityLineAddressLbl: UILabel!
@IBOutlet weak var postcodeLineAddressLbl: UILabel!
@IBOutlet weak var numberLbl: UILabel!
@IBOutlet weak var startBtn: UIButton!
@IBOutlet weak var distanceLbl: UILabel!
@IBOutlet weak var metricLbl: UILabel!
func updateUI(addressObj: DeliveryDestinations) {
//Drow your cell with values from addressObj
firstLineAddressLbl.text = addressObj.FirstLineAddress
secondLineAddressLbl.text = addressObj.SecondLineAddress
cityLineAddressLbl.text = addressObj.CityLineAddress
postcodeLineAddressLbl.text = addressObj.PostcodeLineAddress
}
}
And your result will be:
And here is your updated code.
Maintain an array that contains the data.
//In your MainVC
var deliveryDestinationDataArray = [DeliveryDestinations]()
IN delegate method, you need to save data to the data source.
func userDidEnterData(firstAddress: String, secondAddress: String, cityAddress: String, postcodeAddress: String) {
let deliveryDestinationData = DeliveryDestinations(FirstLineAddress: firstAddress, SecondLineAddress: secondAddress, CityLineAddress: cityAddress, PostCodeLineAddress: postcodeAddress)
deliveryDestinationDataArray.append(deliveryDestinationData)
}
In cellForRowAtIndexPath
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "deliveryAddressCell", for: indexPath) as! AddressCell
cell.updateUI(deliveryDestinationData:deliveryDestinationDataArray[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//change count with deliveryDestinationDataArray count
return deliveryDestinationDataArray.count
}
Update your cell with data
func updateUI(with dataModel: DeliveryDestinations) {
firstLineAddressLbl.text = dataModel.FirstLineAddress
secondLineAddressLbl.text = dataModel.SecondLineAddress
cityLineAddressLbl.text = dataModel.CityLineAddress
postcodeLineAddressLbl.text = dataModel.PostcodeLineAddress
}
Now in viewWillAppear, you need to reload the tableview.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
deliveryAddress.reloadData()
}
Replace your FirstVC with following lines of code:
import UIKit
class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource, DataSentDelegate {
@IBOutlet weak var deliveryAddress: UITableView!
var dataModels: [DeliveryDestinations] = [DeliveryDestinations]()
override func viewDidLoad() {
super.viewDidLoad()
deliveryAddress.delegate = self
deliveryAddress.dataSource = self
deliveryAddress.reloadData()
}
func userDidEnterData(firstAddress: String, secondAddress: String, cityAddress: String, postcodeAddress: String) {
let newEntry: DeliveryDestinations = DeliveryDestinations(FirstLineAddress: firstAddress, SecondLineAddress: secondAddress, CityLineAddress: cityAddress, PostCodeLineAddress: postcodeAddress)
dataModels.append(newEntry)
deliveryAddress.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataModels.count()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "deliveryAddressCell", for: indexPath) as! AddressCell
let dataModel = dataModels[indexPath.row]
cell.updateUI(with: dataModel)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 165
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "addDeliveryAddressVC" {
let addDestination:AddingDestinationVC = segue.destination as! AddingDestinationVC
addDestination.delegate = self
}
}
and Custom cell class with :
import UIKit
class AddressCell: UITableViewCell {
@IBOutlet weak var firstLineAddressLbl: UILabel!
@IBOutlet weak var secondLineAddressLbl: UILabel!
@IBOutlet weak var cityLineAddressLbl: UILabel!
@IBOutlet weak var postcodeLineAddressLbl: UILabel!
@IBOutlet weak var numberLbl: UILabel!
@IBOutlet weak var startBtn: UIButton!
@IBOutlet weak var distanceLbl: UILabel!
@IBOutlet weak var metricLbl: UILabel!
func updateUI(with dataModel: DeliveryDestinations) {
firstLineAddressLbl.text = dataModel.FirstLineAddress
secondLineAddressLbl.text = dataModel.SecondLineAddress
cityLineAddressLbl.text = dataModel.CityLineAddress
postcodeLineAddressLbl.text = dataModel.PostcodeLineAddress
}
}
Also, you should declare your property names in camel case format.
来源:https://stackoverflow.com/questions/47843547/pass-data-back-to-previous-vc-using-delegates-and-update-custom-cell
