前提・実現したいこと
Xcode11.3
Swift5
macOSMojave10.14.6
フェイスブックのコメントボタンを押した時のような、TableViewのタイムライン画面から個別の画面に遷移
↓
TextFieldにコメントを入力後、投稿ボタンを押すと、遷移前のタイムライン画面でタップしたセルと同じポストデータにコメント文が追加され、遷移後のページにあるUILabelかUITextViewにコメントが投稿される
↓
別のユーザーがコメント投稿すると下に増えていく
タイムライン画面ではUItableViewを使い、それぞれのセルはxibファイルを使い、データベースはFirebaseを使ってます。
遷移先にはUIView,UIButton,UILabel(UITextView)があります。
発生している問題・エラーメッセージ
上記
「遷移前のタイムライン画面でタップしたセルと同じポストデータにコメント文が追加され、遷移後のページにあるUILabelかUITextViewにコメントが投稿される」
の実装がわからずあれこれやってもindexPath.rowを渡す・受け取るの部分ができません。
該当のソースコード
●タイムライン画面
swift
1import UIKit 2import Firebase 3 4class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 5 6 @IBOutlet weak var tableView: UITableView! 7 8 var postArray: [PostData] = [] 9 10 // DatabaseのobserveEventの登録状態を表す 11 var observing = false 12 13 override func viewDidLoad() { 14 super.viewDidLoad() 15 16 tableView.delegate = self 17 tableView.dataSource = self 18 19 let nib = UINib(nibName: "PostTableViewCell", bundle: nil) 20 tableView.register(nib, forCellReuseIdentifier: "Cell") 21 22 // テーブル行の高さをAutoLayoutで自動調整する 23 tableView.rowHeight = UITableView.automaticDimension 24 // テーブル行の高さの概算値を設定しておく 25 // 高さ概算値 = 「縦横比1:1のUIImageViewの高さ(=画面幅)」+「いいねボタン、キャプションラベル、その他余白の高さの合計概算(=100pt)」 26 tableView.estimatedRowHeight = UIScreen.main.bounds.width + 100 27 } 28 29 override func viewWillAppear(_ animated: Bool) { 30 super.viewWillAppear(animated) 31 print("DEBUG_PRINT: viewWillAppear") 32 33 if Auth.auth().currentUser != nil { 34 if self.observing == false { 35 // 要素が追加されたらpostArrayに追加してTableViewを再表示する 36 let postsRef = Database.database().reference().child(Const.PostPath) 37 postsRef.observe(.childAdded, with: { snapshot in 38 print("DEBUG_PRINT: .childAddedイベントが発生しました。") 39 40 // PostDataクラスを生成して受け取ったデータを設定する 41 if let uid = Auth.auth().currentUser?.uid { 42 let postData = PostData(snapshot: snapshot, myId: uid) 43 self.postArray.insert(postData, at: 0) 44 45 // TableViewを再表示する 46 self.tableView.reloadData() 47 } 48 }) 49 // 要素が変更されたら該当のデータをpostArrayから一度削除した後に新しいデータを追加してTableViewを再表示する 50 postsRef.observe(.childChanged, with: { snapshot in 51 print("DEBUG_PRINT: .childChangedイベントが発生しました。") 52 53 if let uid = Auth.auth().currentUser?.uid { 54 // PostDataクラスを生成して受け取ったデータを設定する 55 let postData = PostData(snapshot: snapshot, myId: uid) 56 57 // 保持している配列からidが同じものを探す 58 var index: Int = 0 59 for post in self.postArray { 60 if post.id == postData.id { 61 index = self.postArray.firstIndex(of: post)! 62 break 63 } 64 } 65 66 // 差し替えるため一度削除する 67 self.postArray.remove(at: index) 68 69 // 削除したところに更新済みのデータを追加する 70 self.postArray.insert(postData, at: index) 71 72 // TableViewを再表示する 73 self.tableView.reloadData() 74 } 75 }) 76 77 // DatabaseのobserveEventが上記コードにより登録されたため 78 // trueとする 79 observing = true 80 } 81 } else { 82 if observing == true { 83 // ログアウトを検出したら、一旦テーブルをクリアしてオブザーバーを削除する。 84 // テーブルをクリアする 85 postArray = [] 86 tableView.reloadData() 87 // オブザーバーを削除する 88 let postsRef = Database.database().reference().child(Const.PostPath) 89 postsRef.removeAllObservers() 90 91 // DatabaseのobserveEventが上記コードにより解除されたため 92 // falseとする 93 observing = false 94 } 95 } 96 } 97 //セルの数を決めるメソッド 98 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 99 return postArray.count 100 } 101 //セルを構築する際に呼ばれるメソッド 102 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 103 // セルを取得してデータを設定する 104 let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! PostTableViewCell 105 cell.setPostData(postArray[indexPath.row]) 106 107 // セル内のボタンのアクションをソースコードで設定する 108 cell.likeButton.addTarget(self, action:#selector(handleButton(_:forEvent:)), for: .touchUpInside) 109 110 return cell 111 } 112 113 //セルをタップしたら...のメソッド 114 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 115 116 // タップされたセルの行番号を出力 117 print("(indexPath.row)番目の行が選択されました。") 118 119 let postData = postArray[indexPath.row] 120 121 //記事画面へ遷移(セグエ) 122 let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "Article") as! ArticleViewController 123 //completionでSetPostDataに渡す 124 self.present(nextVC, animated: true, completion: { 125 nextVC.SetPostData(postData) 126 }) 127 performSegue(withIdentifier: "Article", sender: postArray[indexPath.row]) 128 //セルの選択を解除 129 tableView.deselectRow(at: indexPath, animated: true) 130 131 } 132}
●遷移後のコメント投稿画面
swift
1import UIKit 2import Firebase 3import SVProgressHUD 4 5class ArticleViewController: UIViewController,UITextFieldDelegate { 6 7 @IBOutlet weak var ArticleImage: UIImageView! 8 @IBOutlet weak var ArticleLabel: UILabel! 9 @IBOutlet weak var ArticleButton: UIButton! 10 @IBOutlet weak var ArticleLilkeCount: UILabel! 11 @IBOutlet weak var CommentLabel: UILabel! 12 @IBOutlet weak var CommentTextField: UITextField! 13 //postarrayの配列 14 var postArray: [PostData] = [] 15 16 override func viewDidLoad() { 17 super.viewDidLoad() 18 self.CommentTextField.delegate = self 19 CommentTextField.returnKeyType = .done 20 } 21 22 func SetPostData(_ postData: PostData) { 23 //イメージ画像 24 self.ArticleImage.image = postData.image 25 //キャプションのテキスト 26 self.ArticleLabel.text = "(postData.name!) : (postData.caption!)" 27 //いいねの数 28 let likeNumber = postData.likes.count 29 ArticleLilkeCount.text = "(likeNumber)" 30 31 //いいねボタン 32 if postData.isLiked { 33 let buttonImage = UIImage(named: "like_exist") 34 self.ArticleButton.setImage(buttonImage, for: .normal) 35 } else { 36 let buttonImage = UIImage(named: "like_none") 37 self.ArticleButton.setImage(buttonImage, for: .normal) 38 } 39 //allCommentは最初は空である 40 var allComment = "" 41 42 //postData.commentsの中から要素をひとつずつ取り出すのを繰り返す、というのがcomment 43 for comment in postData.comments{ 44 //comment + comment = allCommentである 45 allComment += comment 46 //commentLabelに表示するのはallComment(commentを足していったもの)である 47 self.CommentLabel.text = allComment 48 } 49 } 50 51 //キーボードを閉じる 52 @IBAction func textField(_ sender: Any) { 53 CommentTextField.text = (sender as AnyObject).text 54 } 55 //コメント投稿ボタン 56 @IBAction func CommentButton(_ sender: UIButton,_ postData: PostData,indexPath: IndexPath) { 57 58 let indexPath = postArrey[indexPath.row], 59 //現在の使用者の表示名がnilじゃなかったら、displayNameに代入し、 60 if let displayName = Auth.auth().currentUser?.displayName, 61 //cell.textField.textをtextと定義する 62 let commentText = self.CommentTextField.text { 63 64 //であれば、cell(PostTableViewCell)のtextFieldをプリントする 65 print(self.CommentTextField.text as Any) 66 67 //であれば、postData.commentsにtextをappend(追加)する 68 postData.comments.append("(displayName): (commentText)\n") 69 70 } 71 72 // 増えたcommentsをFirebaseに保存する 73 let postRef = Database.database().reference().child(Const.PostPath).child(postData.id!) 74 //comments辞書 75 let commentDictionary = ["comments": postData.comments] 76 //Firebaseに辞書を保存する 77 postRef.updateChildValues(commentDictionary) 78 } 79}
試したこと
遷移前ページのdidSelectRowAt内で
performSegue(withIdentifier: "Article", sender: postArray[indexPath.row]) ```でセルの行番号を送ろうとしていますが、合っているのかがわかりません。 遷移後ページのアクションボタン内で
@IBAction func CommentButton(_ sender: UIButton,_ postData: PostData,indexPath: IndexPath) {
let indexPath = postArrey[indexPath.row], //現在の使用者の表示名がnilじゃなかったら、displayNameに代入し、 if let displayName = Auth.auth().currentUser?.displayName, //cell.textField.textをtextと定義する let commentText = self.CommentTextField.text { //であれば、cell(PostTableViewCell)のtextFieldをプリントする print(self.CommentTextField.text as Any) //であれば、postData.commentsにtextをappend(追加)する postData.comments.append("(displayName): (commentText)\n") }
遷移前でのセル行番号を取得する方法がわかりません。 色々調べてもたどり着けませんでした。

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。