

はじめまして。業務経験２ヶ月ほどのエンジニアです。  
業務でswiftを使用するため、勉強をしており、以下のことを解決できずに数日悩んでおります。  
どなたか解決の糸口をご教示いただけますと幸いです。

# やりたいこと

ViewController (tableViewを配置している)  
ButtonCell （ボタンを2つ配置しているセル)

cellのボタンを押下された場合、tableViewを配置しているviewControllerのメソッドを呼び出し、statusプロパティの更新とtableView.reloadDataをやりたい

# 問題点

tableViewがnilとなってしまい、tableView.reloadData()が実行できない。

記述したコード（ほとんど省力しています）  
■ViewController (tableviewを配置しているクラス)

[code]

    import UIKit
    
    class ViewController: BaseVC ,UITableViewDelegate, UITableViewDataSource {
        
    
        @IBOutlet private weak var tableView: UITableView!
        var status:Int = 1
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
       
        func numberOfSections(in tableView: UITableView) -> Int {
    //　省略
        }
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // 省略
        }
    
        func didTap() {
            self.status = 2
           tableView.reloadData()
        }
    
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    //省略　（ここでButtonを定義しているcellクラスを呼び出している)
        }
        
    }
    
[/code]

■Buttonを定義したCellクラス

[code]

    import UIKit
    
    
    class ButtonCell: UITableViewCell {
    
        @IBOutlet weak var Button1: UIView!
        @IBOutlet weak var Button2: UIView!
    
    
        override func awakeFromNib() {
            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()
        }
        
    }
    
[/code]

# 試したこと

  * storyboardのtableViewがViewControllerと接続が切れていないか、確認。
  * 以下に記述している内容を参考に、以下のコードを試してみる。

[code]

     let vc = storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController
    vc.tableView.reloadData()
    
[/code]

<https://teratail.com/questions/308093>  
→結果はどちらもうまくいかず、、


CC BY-SA 4.0
2022-05-03T12:31:01.917
88637
2022-05-05T11:14:33.310
52464
question
swift tableview
swift tableviewがnilとなる問題について

[code]

    class ButtonCell: UITableViewCell {
    
        // 省略
        
        @objc private func change1() {
             ViewController().didTap() // ここ
        }
        
        @objc private func change2() {
            ViewController().didTap() // ここ
        }
        
    }
    
[/code]

クラス`ButtonCell`の中の`ViewController().didTap()`が問題を抱える箇所です。  
この行には、ふたつの問題があります。  
一つは、クラス`ViewController`のイニシアライザ`ViewController()`は、Storyboardをベースにせずにインスタンスを生成・初期化するという点です。Storyboardを使わないのですから、プロパティ`var
tableView:
UITableView!`は`nil`のままです。参考としてお示しになっているメソッド`instantiateViewController(withIdentifier:
"ViewController")`は、Storyboardを使わないイニシアライザであることを明白にするサンプルです（そして、問題解決の方法を示しているわけでは、けっしてありません）。  
もう一つの問題は、イニシアライザは、新規にインスタンスを生成するものであって、それは既存のインスタンスと別物のインスタンスであるという点です。別物に対して「tableViewをreloadしてね」と指示しても、なんの役にも立たないことは、ご理解いただけますね？

* * *

なすべきは、`ButtonCell`クラスのインスタンスに、既存の`ViewController`クラスのインスタンスの **参照** を引き渡すことです。

●クラス`ButtonCell`

[code]

    class ButtonCell: UITableViewCell {
    
        @IBOutlet weak var Button1: UIView!
        @IBOutlet weak var Button2: UIView!
    
        weak var viewController: ViewController? // 追加
    
        // 省略
        
        @objc private func change1() {
             viewController?.didTap() // 変更
        }
        
        @objc private func change2() {
            viewController?.didTap() // 変更
        }
        
    }
    
[/code]

●クラス`ViewController`

[code]

    class ViewController: BaseVC ,UITableViewDelegate, UITableViewDataSource {
        
        @IBOutlet private weak var tableView: UITableView!
    
        func didTap() {
            self.status = 2
            tableView.reloadData()
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Storyboardで指定した識別子", for: indexPath) as! ButtonCell
            cell.viewController = self // ButtonCellにviewControllerの参照を渡す。
    
            return cell
        }
        
        // 省略
    }
    
[/code]

解決案のひとつを示したコードです。


CC BY-SA 4.0
2022-05-05T06:06:03.427
88654
2022-05-05T11:14:33.310
2022-05-05T11:14:33.310
18540
18540
88637
answer