Swift 使用委托表视图刷新另一个类的内容



我需要从另一个对外部API执行异步调用的类更新TableView的内容。

我实现了一个协议来在 API 调用后刷新表,但似乎从未执行过这段代码。 我不明白我的代码出了什么问题。可能我忘记了一些东西,这是我的第一个应用程序,我刚刚开始研究协议实现

下面我写了一个代码示例,其中删除了所有不必要的代码(针对此问题(。

协议定义:

protocol ProductUpdateDelegate: class {
func refreshTableView()
}

塔贝尔维尤实现:

class TestTableViewController: UITableViewController,
UITextFieldDelegate, ProductUpdateDelegate {
var productList = [productInfo]()
// Delegate function implementation
func refreshTableView() {
self.tableView.reloadData()
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = 50;
self.tableView.dataSource = self
self.tableView.delegate = self
more code ...
}
@IBAction private func buttonTappedAction(_ sender: Any) {
code that get input from user and did some check...
if(isValidCode){
self.storeProduct(productCode: code)        
}
}

func storeProduct(productCode: String){
if(isNewCode){
self.productList.append(productInfo(code: productCode,
quantity: 1))
}
more code ...
}

需要更新表视图上某些信息的类

import Foundation
class Product {
weak var delegate: ProductUpdateDelegate?
some code here...
func getProductInfoFromAPI(){
API CAll...
if(result != "no_data")
self.delegate?.refreshTableView()
}
more code ...
}

类,用于存储有关产品的信息,并用于使用远程 API 更新产品描述

import Foundation
class productInfo: NSObject, NSCoding, Codable {
var code = ""
var quantity = 1
public var product_name = "Wait for information..."
init(code: String, quantity : Int, 
product_name : String = "Wait for information...") {
self.code = code
self.quantity = quantity
self.product_name = product_name
super.init()
self.getProductInfoFromAPI()
}
required convenience init(coder aDecoder: NSCoder) {
let code = aDecoder.decodeObject(forKey: "code") as! String
let quantity = aDecoder.decodeInteger(forKey: "quantity")
self.init(code:code, quantity:quantity)
self.getProductInfoFromAPI()
}
func getProductInfoFromAPI(){
let productInfo = Product()
productInfo.getInfoByCode(productCode: code, refObject: self)
}

func encode(with aCoder: NSCoder) {
aCoder.encode(self.code, forKey: "code")
aCoder.encode(self.quantity, forKey: "quantity")
}
}

UPDATE1:产品类是从其他一些类(总共 4 个(调用的,为了简单起见,我在这里没有包括这些类

应用程序工作流为:

  • 应用程序启动
  • 显示测试表视图控制器

然后,用户可以使用一些不同的选项来更新 TableView 内容,每个选项都由单独的类控制,因此产品类是从其他一些类调用的,并且是唯一直接与 TestTableViewController 交互

的类UPDATE2:添加更多代码以显示完整过程。 视图初始化后,用户可以单击按钮并可以插入产品代码。

插入的代码使用 append 保存在产品信息数组中。此操作将激活 productInfo 类的 init 方法,并开始调用远程服务以检索有关产品本身的信息。

问题是文章信息已正确更新,但由于视图未更新,因此未显示在表视图中。 因为是一个异步过程,所以我需要一种方法在检索过程完成后更新视图内容。 所以我认为最好的解决方案是协议。但如前所述,函数 refreshTableView 似乎被忽略了。

var refreshControl = UIRefreshControl()
@IBOutlet weak var tblView: UITableView!

override func viewDidLoad() {
super.viewDidLoad()
refreshControl.attributedTitle = NSAttributedString(string: "")
refreshControl.addTarget(self, action: #selector(refresh(sender:)), for: UIControl.Event.valueChanged)
tblView.addSubview(refreshControl)
}

@objc func refresh(sender:AnyObject) {
refreshControl.endRefreshing()
apiFunction()
}

func apiFunction(){
// call your api
}

根据你的代码,你没有为类中名为delegateProduct弱变量设置任何值。您应该将其设置为应该使用它的类。 一种方法是将Product类设置为单例,使其仅初始化一次。 例如

class Product {
static let shared = Product()
weak var delegate: ProductUpdateDelegate?
private init() { }
func getProductInfoFromAPI(){
if(result != "no_data")
self.delegate?.refreshTableView()
}
}

在表视图控制器中,您可以使用let productInfo = Product.shared而不是let productInfo = Product()然后设置委托。

productInfo.delegate = self

就是这样!

最新更新