如何在 Swift 中重新初始化 UITableViewCell?

How can I reinitialize a UITableViewCell in Swift?

我正在使用 UITableViewCell 来显示数据。加载视图时,数据为空,但是一旦 api 调用完成,我想重新初始化 UITableViewCell 以便显示数据。我正在使用以下代码,但 TableView.reloadData() 不会重新初始化 UITableViewCell,因此不会重新加载数据。

TableViewCell

class TableViewCell: UITableViewCell {
    
    var Info: Information?
    let Chart = LineChartView(frame: .zero)
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        print("initialized")
        self.contentView.addSubview(Chart)
        Chart.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            Chart.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10),
            Chart.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -10),
            Chart.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -10),
            Chart.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 10),
        ])
        let data = ChartHelpers().makeLineChart(data: Info?.Values ?? [Double]())
        Chart.data = data
        self.contentView.layoutIfNeeded()
     }

     required init?(coder aDecoder: NSCoder) {
       super.init(coder: aDecoder)
    }
}

ViewController


class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var Info: Information?
    let TableView = UITableView(frame: .zero)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        APICall()
        setUpUI()
    }

    func setUpUI() {
        view.addSubview(TableView)
        TableView.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            TableView.topAnchor.constraint(equalTo: view.topAnchor),
            TableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            TableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            TableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        ])
        self.TableView.register(TableViewCell.self, forCellReuseIdentifier: "Chart")
        TableView.delegate = self
        TableView.dataSource = self
        TableView.reloadData()
        view.layoutIfNeeded()
    }

    func APICall() {
        API().fetchInformation(Name: "John Doe") { (Info) in
            //success connecting to api
            DispatchQueue.main.async {
                self.Info = Info
                self.TableView.reloadData()
            }
        } failure: { (error) in
            //failure connecting to api

            }
        }
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = TableView.dequeueReusableCell(withIdentifier: "Chart", for: indexPath) as! TableViewCell
        tableView.rowHeight = 300
        cell.Info = self.Info
        return cell
    }
}

最好不要在init中配置,cell实例可能会被复用。将单元格出队时应进行设置。这可以通过设置方法或通过设置属性来完成,就像您在此处使用 Info 所做的那样(顺便说一下,将其命名为 info)。

在这里获得您想要的内容的最简单方法是将 didSet 添加到您的 Info 属性 并在那里调用设置方法:

var info: Information? {
    didSet {
        let data = ChartHelpers().makeLineChart(data: Info?.Values ?? [Double]())
        Chart.data = data
        self.contentView.layoutIfNeeded()
    }
}

虽然其他重构可能会更好 运行。

didSet 添加到您的 Info 变量以触发构建图表。

var Info: Information? {
   didSet {
     let data = ChartHelpers().makeLineChart(data: Info?.Values ?? [Double]())
     Chart.data = data
     self.contentView.layoutIfNeeded()
   }
}

didSet 观察器在初始化期间不会触发,因此当您在 API 调用后有有效数据时单元格重新加载时,您需要再次调用序列。