概要
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
ポイントは二つかなと思います。
- プロトコルの設置
- delegateの宣言(?)
画面遷移はあくまでViewControllerから行います。なので、TableViewCell上にボタンを配置し、IBActionで接続したとしても動かないんですね。
なのでdelegateを使って処理を委託する必要があります。
(delegateに関しても多くの人が記事を書いてくれているのでそちらを参考にしてみてください)
MainViewController
こちらで付け加える部分は3箇所。
- プロトコルの宣言
- 動きたい処理(今回であれば画面遷移)を書く関数の記述
- cell?.delegate = self
この cell?.delegate = self
があるお陰で関数が動いてくれます。こいつがdelegateの委託を受け取ってくれているんですね。
感想
まだまだ理解が浅いとこの記事を書いていても実感。指摘点がある方、是非コメントで教えていただけると幸いです。
参考
プロトコル名などそのまま拝借しましたm(_ _)m
https://qiita.com/antk/items/4934aa634d679e1dc099