【问题标题】:Pass data back to previous VC using delegates and update custom cell使用委托将数据传回之前的 VC 并更新自定义单元格
【发布时间】:2018-05-30 07:48:18
【问题描述】:

我正在尝试使用委托将数据 BACK 传递给之前的 viewController

有谁知道如何将数据从ViewController B 传回ViewController A

所以我想将数据从SecondVC 传递到FirstVC,并使用SecondVC 4 地址文本字段中的数据更新自定义表格视图单元格,但由于某种原因,它根本没有更新。

任何帮助都将不胜感激,因为我才刚刚起步,所以尝试了各种各样的事情,但无法让它发挥作用。

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
    }


}

}

第二个VC

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

}
}

自定义单元

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

}

模型文件

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
    }

}

【问题讨论】:

  • 您需要将模型添加到 ViewController 并使用 TableView.reload 数据进行更新,并使用来自您的 AdditionalDestinationVC 的新更新数据
  • 在这里看到很多错误。可以分享一下演示项目吗?
  • @DharmeshKheni 我有 github 网址 github.com/Marius-Dragan/iDeliver/tree/03-PassingData

标签: ios iphone swift swift3 xcode9


【解决方案1】:

检查以下更正的代码:

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
        }
    }
}

添加目的地VC:

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

地址单元:

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
    }
}

你的结果将是:

here 是您更新后的代码。

【讨论】:

  • 它成功了,谢谢你是这件事的巫师,我会努力记住这一点。非常感谢。
  • 您在 swift 方面经验丰富,能否提供任何有用的信息链接,以帮助我学习并获得初级 ios 开发人员工作?
  • 如果我想用表中的项目数更新红色标签,我还需要进入数据模型来创建变量并在第二个 vc 中初始化它吗?
  • 我所做的是这样的cell.numberLbl.text = String(indexPath.row + 1) 这是好的做法吗?我已经把它放在cellForRowAt indexPath: 并且它正在完美更新。
【解决方案2】:

维护一个包含数据的数组。

//In your MainVC
var deliveryDestinationDataArray =  [DeliveryDestinations]()

IN委托方法,需要将数据保存到数据源。

func userDidEnterData(firstAddress: String, secondAddress: String, cityAddress: String, postcodeAddress: String) {
    let deliveryDestinationData = DeliveryDestinations(FirstLineAddress: firstAddress, SecondLineAddress: secondAddress, CityLineAddress: cityAddress, PostCodeLineAddress: postcodeAddress)
    deliveryDestinationDataArray.append(deliveryDestinationData)
}

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
}

用数据更新你的单元格

 func updateUI(with dataModel: DeliveryDestinations) {
    firstLineAddressLbl.text = dataModel.FirstLineAddress
    secondLineAddressLbl.text = dataModel.SecondLineAddress
    cityLineAddressLbl.text = dataModel.CityLineAddress
    postcodeLineAddressLbl.text = dataModel.PostcodeLineAddress
}

现在在viewWillAppear中,您需要重新加载tableview

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    deliveryAddress.reloadData()
}

【讨论】:

    【解决方案3】:

    将您的 FirstVC 替换为以下代码行:

        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
    }
    

    }

    和自定义单元格类:

    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
        }
    
    }
    

    此外,您应该以驼峰格式声明您的属性名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-08
      • 2016-05-01
      • 1970-01-01
      相关资源
      最近更新 更多