如何使用委托协议更新tableView数据?

时间:2018-01-24 11:51:19

标签: ios swift

我正在创建没有故事板的应用程序。 我使用Delegate协议在我的2个控制器之间传递数据

@Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    task = new AsyncTask<Void, Void, String>() {
        @Override protected String doInBackground(Void... params) {
            return requestFromServer("<api call>");
        }

        @Override protected void onPostExecute(String s) {
            if (!isFinishing() && !isCancelled()) {
                Log.d("Request", s);
                Toast.makeText(ExampleActivity.this, "Request performed", Toast.LENGTH_LONG).show();
            }
        }
    };
}

@Override protected void onDestroy() {
    super.onDestroy();

    if (task != null) {
        task.cancel(true);
        task = null;
    }
}

我在我的ProductDetailController上获取数据,func transferProduct可以打印它但我需要使用这些新数据更新我的tableView但由于某些原因self.tableView.reloadData()对我不起作用。

protocol CatalogueDelegate {
    func transferProduct(product: JSONProduct?)
}

class CatalogueController: UITableViewController{

var catalogueDelegate: CatalogueDelegate!

override func viewDidLoad() {
    super.viewDidLoad()

    feetchLabelProducts(labelId: 2, qnt: nil) 
}

private func feetchLabelProducts(labelId: Int, qnt: Int?) {
    getLabelProducts(labelId: labelId, qnt: qnt, completed: {
        self.tableView.reloadData()
    })
}

private func getLabelProducts(labelId: Int, qnt: Int?, completed: @escaping () -> ()) {
    APIService.shared.downloadLabelProducts(labelId: labelId, qnt: qnt) { (products, error) in
        if let products = products {
            self.productList = products
        }

        DispatchQueue.main.async {
            completed()
        }
    }
}

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return productList.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellProductId, for: indexPath) as! ProductCell
        cell.product = self.productList[indexPath.row]
        return cell
    }
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let product = self.productList[indexPath.row]
    catalogueDelegate.transferProduct(product: product)
    let productDetailVC = ProductDetailController()
    navigationController?.pushViewController(productDetailVC, animated: true)
}    
}
你能帮我解决这个问题吗? 我可以打印收到的数据

import UIKit

class ProductDetailController: UIViewController, UITableViewDelegate, UITableViewDataSource {

let productDetailCell = "productDetailCellId"
var product: JSONProduct?

let tableView: UITableView = {
    let tableView = UITableView()
    return tableView
}()

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.register(ProductDetailCell.self, forCellReuseIdentifier: productDetailCell)
    tableView.delegate = self
    tableView.dataSource = self
    tableView.separatorColor = UIColor.clear

    view.addSubview(tableView)

    view.backgroundColor = UIColor.white

    _ = tableView.anchor(view.topAnchor, left: view.leftAnchor, bottom: buyButton.topAnchor, right: view.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: productDetailCell, for: indexPath) as! ProductDetailCell

    if let product = self.product {
        print(product.title)
    } else {
        print("No data!!!")
    }

    return cell
}

}

extension ProductDetailController: CatalogueDelegate {
func transferProduct(product: JSONProduct?) {
    guard let item = product else { return }
    self.product = item
    self.tableView.reloadData()
}
}

我确实在AppDelegate文件中设置了委托,如此

extension ProductDetailController: CatalogueDelegate {
func transferProduct(product: JSONProduct?) {
    guard let item = product else { return }
    // I can print new data
    print(item)
    // But I can not update my tablveView with thith new data
    self.product = item
    tableView.reloadData()
}
}

1 个答案:

答案 0 :(得分:0)

您忘记将cellForRowAt中的数据设置为单元格:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: productDetailCell, for: indexPath) as! ProductDetailCell

    if let product = self.product {
        // you have to set that product to the cell
        print(product.title)
    } else {
        print("No data!!!")
    }

    return cell
}

修改

didSelectRowAt中的CatalogueController重写为以下内容:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let product = self.productList[indexPath.row]
    let productDetailVC = ProductDetailController()
    productDetailVC.transferProduct(product: product)
    navigationController?.pushViewController(productDetailVC, animated: true)
} 

我不确定您之前在哪里设置delegate,但是您提出的新productDetailVC不是您调用transferProduct()的代理人。如果这是您的整个设置,您不需要委托模式,您只需要执行此操作:

let productDetailVC = ProductDetailController()
productDetailVC.transferProduct(product: product)
navigationController?.pushViewController(productDetailVC, animated: true)

编辑2

发生这种情况的原因很简单。您在delegate

中设置了AppDelegate
let productDetailController = ProductDetailController()
let catalogueController = CatalogueController() 
catalogueController.catalogueDelegate = productDetailController

但是在这里你提出另一个不同的视图控制器:

let product = self.productList[indexPath.row]
// this sets a product to the delegate object
catalogueDelegate.transferProduct(product: product)
// but the following two lines present another new view controller,
// not the one that is the delegate!
let productDetailVC = ProductDetailController()
navigationController?.pushViewController(productDetailVC, animated: true)