Understanding the Issue of nil in the Swift tableview

Asked 2 years ago, Updated 2 years ago, 81 views

Nice to meet you.I'm an engineer with about 2 months of work experience.
As I am studying to use Swift for my business, I have been having trouble solving the following problems for a few days.
I would appreciate it if someone could give me a clue to the solution.

ViewController (with tableView)
ButtonCell (cell with two buttons)

If you press the cell button, I want to call the viewController method where tableView is located, update status properties, and do tableView.reloadData

TableView is now nil and cannot run tableView.reloadData().

Described code (mostly saved)
■ ViewController (class with tableview)

import UIKit

classViewController: BaseVC, UITableViewDelegate, UITableViewDataSource {
    

    @IBOutlet private wide variableView:UITableView!
    var status —Int=1

    override func viewDidLoad(){
        super.viewDidLoad()
    }
   
    func numberOfSections (tableView: UITableView) - > Int {
// omission
    }
    
    functableView(_tableView:UITableView, numberOfRowsInSection section:Int) - > Int{
// omission
    }

    func didTap(){
        self.status=2
       tableView.reloadData()
    }

    
    functableView(_tableView:UITableView, cellForRowAtindexPath:IndexPath) - >UITableViewCell{
// Omitted (call the cell class defining Button here)
    }
    
}

■ Cell Class Defined by Button

import UIKit


classButtonCell:UITableViewCell{

    @IBOutlet weak var Button1: UIView!
    @IBOutlet weak var Button 2: UIView!


    override funcawakeFromNib(){
        super.awakeFromNib()
    }

    override func setSelected(_selected:Bool, animated:Bool) {
        super.setSelected(selected, animated:animated)
    }
    
    @objc private func change1(){
         ViewController().didTap()
    }
    
    @objc private func change2(){
        ViewController().didTap()
    }
    
}
  • Verified that the tableView on the storyboard is disconnected from the ViewController.
  • Try the code below with reference to what is written below.
let vc=storyboard?instantiateViewController(withIdentifier: "ViewController") as!ViewController
vc.tableView.reloadData()

https://teratail.com/questions/308093
→ Both results are not successful.

swift tableview

2022-09-30 14:41

1 Answers

class ButtonCell:UITableViewCell{

    // omission
    
    @objc private func change1(){
         ViewController().didTap()//Here
    }
    
    @objc private func change2(){
        ViewController().didTap()//Here
    }
    
}

The ViewController().didTap() in the class ButtonCell is the problem.
There are two problems with this line.
One is that the Initiator ViewController() in class ViewController generates and initializes instances without being based on the Storyboard.The property variableView:UITableView! remains nil because it does not use Storyboard.The suggested method instantiateViewController (withIdentifier: "ViewController") is a sample that makes it clear that you are an Initiator without Storyboard (and it does not show you how to resolve the issue).
Another problem is that initiators create new instances, which are separate from existing ones.Do you understand that instructing someone else to reload the tableView is of no use?

What you should do is pass an reference of an existing ViewController class instance to an instance of the ButtonCell class.

● Class ButtonCell

class ButtonCell:UITableViewCell{

    @IBOutlet weak var Button1: UIView!
    @IBOutlet weak var Button 2: UIView!

    peak var viewController:ViewController ?/ Add

    // omission
    
    @objc private func change1(){
         viewController ?.didTap()//Change
    }
    
    @objc private func change2(){
        viewController ?.didTap()//Change
    }
    
}

● Class ViewController

class ViewController: BaseVC, UITableViewDelegate, UITableViewDataSource{
    
    @IBOutlet private wide variableView:UITableView!

    func didTap(){
        self.status=2
        tableView.reloadData()
    }

    functableView(_tableView:UITableView, cellForRowAtindexPath:IndexPath) - >UITableViewCell{
        letcell=tableView.dueReusableCell(withIdentifier: "Identifier specified in Storyboard", for:indexPath) as!ButtonCell
        cell.viewController=self// Pass the viewController reference to ButtonCell.

        return cell
    }
    
    // omission
}

This code shows one of the solutions.


2022-09-30 14:41

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.