前提・実現したいこと
Firestoreのデータを表示しているtableViewのセルをタップしたとき、そのセルのドキュメントIDを取得したい。
実現したいことは以下の通りです。
1,タップしたセルのドキュメントIDを取得
2,DetaiviewControllerにそのIDを渡す。
3,DetaiviewControllerにあるgetActionボタンを押したらそのIDの投稿をマイページに保存する
プログラミング始めたてで質問の仕方が適切でないかもしれませんが、回答していただけると嬉しいです。
発生している問題・エラーメッセージ
タップしたセルのドキュメントIDが取得できません。
該当のソースコード
tableviewController
1 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 2 let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TimeLineCell 3 cell.timeLineModel = self.timeLines[indexPath.row] 4 5 return cell 6 } 7 8 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 9 10 let selectedCell = tableView.cellForRow(at: indexPath) 11 musicName = timeLines[indexPath.row].musicName 12 groupName = timeLines[indexPath.row].groupName 13 constitution = timeLines[indexPath.row].constitution 14 15 performSegue(withIdentifier: "detail", sender: nil) 16 } 17 18 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 19 20 if segue.identifier == "detail" { 21 22 let detailViewController = segue.destination as! DetailViewController 23 24 detailViewController.musicName = musicName 25 detailViewController.groupName = groupName 26 detailViewController.constitution = constitution 27 }
TimeLineModel
1import Foundation 2import Firebase 3 4class TimeLineModel { 5 6 var musicName:String = "" 7 var groupName:String = "" 8 var constitution:String = "" 9 var ref = Firestore.firestore().collection("timeLine") 10 11 12 init(musicName:String,groupName:String,constitution:String) { 13 14 self.musicName = musicName 15 self.groupName = groupName 16 self.constitution = constitution 17 } 18 19 init(document:QueryDocumentSnapshot) { 20 21 if let value = document.data() as? [String:Any] { 22 23 musicName = value["musicName"] as! String 24 groupName = value["groupName"] as! String 25 constitution = value["constitution"] as! String 26 } 27 } 28 29 func toContents() -> [String:Any] { 30 return ["musicName":musicName,"groupName":groupName,"constitution":constitution] 31 } 32 33 func save() { 34 ref.addDocument(data: toContents()) 35 } 36
試したこと
https://teratail.com/questions/203222
この記事の方法を試しましたが draftData が何を指すのかわからず理解で解決できませんでした。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
問題の本質がFirestoreに関係してくるとなると判断できない部分もありますが、すくなくとも
tableView(_ :cellForRowAt:)
では、Cell に定義してある timeLineModel に値を渡していますが、タップされた時のメソッド
tableView(_:didSelectRowAt:)
では、タップされたセルのインスタンをを次の方法で得ているものの、
let selectedCell = tableView.cellForRow(at: indexPath)
値の代入は上記の selectedCell を使わずに
musicName = timeLines[indexPath.row].musicName
groupName = timeLines[indexPath.row].groupName
constitution = timeLines[indexPath.row].constitution
と、timeLines を使ってやっているようですが、そのあたりの整合性はどのようになっているのでしょうか。
ご指摘ありがとうございます。
教材のコードを写している部分もあり、恥ずかしながら自分でもよく理解できていなかったですが、渡されている値は正しかったです、、、
selectedCellを使ったやり方をもしよろしければ教えていただきたいです。
tableViewに並んでいる順番とtimeLinesという配列の中の投稿の順番が同じで、timeLines[indexPath.row]と書くことでタップされた投稿の情報を取得できると考えています。
指摘したいことは、tableView(_:indexPath:) でカスタムセル内のプロパティ(変数)にtimeLineModel を代入していますが、その他の場所で一切使えわれていないということです。
2020/12/09 20:25 のコメントでもあるように、配列で保持しているデータとセルのデータの順番が一致しているのであれば、あえてセルにデータを持たせる意味は少ないのではないでしょうか。
ちなみに、それを簡潔に解決されているのが、hameji001さんのご回答です。
セルには情報を持たせず、indexPath を使ってアクセスすべきデータを管理しています。
なるほど、、senderを使ってindexpathの情報ごと送ればその必要はなかったですね!
ありがとうございます!
hajimeさんの回答を参考にまた考え直して見たいと思います!
ご指摘本当にありがとうございました!
sender で送る以外に、下記のプロパティを使って得ることも可能です(非選択状態に戻すと使えないので、使う順番は考える必要がありますが)。
https://developer.apple.com/documentation/uikit/uitableview/1615000-indexpathforselectedrow
この方法でも選択したセルの情報を得ることが出来るんですね。
他にも応用できそうな情報ありがとうございます、とてもためになります!
親切な対応ありがとうございます!
回答1件
あなたの回答
tips
プレビュー