7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Swift] TableViewのカスタムセルに設置したボタンから画面遷移したい!

Last updated at Posted at 2021-10-18

概要

tableViewのカスタムセルに設置したボタンをタップして別のViewControllerを開く(タイトルそのまま)。
今回は二つのボタンを設置して、それぞれのボタンによって違う画面に遷移するようにしたいと思います。

先に言っておきます。筆者も修行中のみでございます。
また、動けば良いという人は下記コードをコピペしてみてください。動きます。

準備

以下、登場人物

  • tableViewを設置するViewControllerファイル(MainViewControllerとします)
  • カスタムセルと紐づいたTableViewCellファイル(CustomTableViewCellとします)

まずはこの二つのファイルを用意してください。これらの設定は他の人がもっとわかりやすく記事にしているのでそちらを参考にしてみてください。

実装

先に全体像をお見せします。

CustomTableViewCell

import UIKit
protocol CatchProtocol {
    func catchData(id:Int)
}

class CustomTableViewCell: UITableViewCell {
    
    var delegate : CatchProtocol?
    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
    
    @IBAction func openFirst(_ sender: UIButton) {
        delegate?.catchData(id: 0)
    }
    
    @IBAction func openSecond(_ sender: UIButton) {
        delegate?.catchData(id: 1)
    }
    
}

続いて、MainViewController


import UIKit

class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CatchProtocol {
   
    @IBOutlet weak var tableView: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.delegate = self
        tableView.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "CustomTableViewCell")
    }
    
    func catchData(id : Int) {
        if id == 0 {
            let baseVC = self
            let storyboard = UIStoryboard(name: "Hoge", bundle: nil)
            let vc = storyboard.instantiateViewController(withIdentifier: "遷移したいViewControllerその1")
            let next = vc
            DispatchQueue.main.async {
                next.modalPresentationStyle = .fullScreen
                baseVC.present(next,animated: true)
            }
        } else if id == 1 {
            let baseVC = self
            let storyboard = UIStoryboard(name: "Hoge", bundle: nil)
            let vc = storyboard.instantiateViewController(withIdentifier: "遷移したいViewControllerその2")
            let next = vc
            DispatchQueue.main.async {
                next.modalPresentationStyle = .fullScreen
                baseVC.present(next,animated: true)
            }
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell")  as? CustomTableViewCell
        cell?.delegate = self
        return cell ?? CustomTableViewCell()
    }
}

簡単に解説

CustomTableViewCell

ポイントは二つかなと思います。

  1. プロトコルの設置
  2. delegateの宣言(?)

画面遷移はあくまでViewControllerから行います。なので、TableViewCell上にボタンを配置し、IBActionで接続したとしても動かないんですね。
なのでdelegateを使って処理を委託する必要があります。
(delegateに関しても多くの人が記事を書いてくれているのでそちらを参考にしてみてください)

MainViewController

こちらで付け加える部分は3箇所。

  1. プロトコルの宣言
  2. 動きたい処理(今回であれば画面遷移)を書く関数の記述
  3. cell?.delegate = self

この cell?.delegate = self があるお陰で関数が動いてくれます。こいつがdelegateの委託を受け取ってくれているんですね。

感想

まだまだ理解が浅いとこの記事を書いていても実感。指摘点がある方、是非コメントで教えていただけると幸いです。

参考

プロトコル名などそのまま拝借しましたm(_ _)m
https://qiita.com/antk/items/4934aa634d679e1dc099

7
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?