質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

5741閲覧

tableViewCellのIndexPathを取得したい。

退会済みユーザー

退会済みユーザー

総合スコア0

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/07/25 02:45

こちら↓の質問から派生しています。
リンク

やりたいこと

データ表示しているtableViewCellのIndexPathIntで取得したいです。

試したこと・試していること

  • macOSのtableViewメソッドにあるselectAllのiOS版(tableViewで使用可能な)がないか探したり尋ねたりしました。

→結果:ないので自作、という結論に。

  • selectRowメソッドをfor in文内で使用し、どのような動きになるのか確認したいと思い試している最中でIndexPathIntで所得できずに詰まっています。(IndexPath(Int)ではなく[IndexPath]で取得してしまっています。)

以下、[IndexPath]で取得してエラーが出ているコードです。なお、tableViewCellに表示させるデータはfirebase firestoreから取得しています。(UITableViewDelegateは省略しております)

swift

1import UIKit 2import Firebase 3 4class DraftViewController: UIViewController, UITextFieldDelegate { 5 6 let db = Firestore.firestore() 7 let user = Auth.auth().currentUser 8 private var draftData:[QueryDocumentSnapshot] = [] 9 10 override func viewDidLoad() { 11 super.viewDidLoad() 12 13 //複数選択できるようにする 14 tableView.allowsMultipleSelectionDuringEditing = true 15   //firestoreのdraftsデータを取得 16 getDraftsData() 17 } 18 19 //firestoreのdraft data を取得 20 func getDraftsData() { 21 guard let uid = user?.uid else { return } 22 db.collection("drafts").whereField("uid", isEqualTo: uid).getDocuments() { (querysnapshot, err) in 23 if let err = err { 24 print("error getting documents: (err)") 25 } else { 26 let personalDraftData = querysnapshot!.documents.sorted {personalDraftData,provisionalDraftData in 27 guard let personalDraftsData = personalDraftData.data()["timestamp"] as? Timestamp, 28 let provisionalDraftsData = provisionalDraftData.data()["timestamp"] as? Timestamp else { return false } 29 return (personalDraftsData.dateValue() > provisionalDraftsData.dateValue()) 30 } 31 32 self.draftData = personalDraftData 33 self.tableView.reloadData() 34 } 35 } 36 } 37}

swift

1extension DraftViewController: UITableViewDataSource { 2 3 @IBAction func tapCloseButton(_ sender: Any) { 4 guard let indexPaths = tableView.indexPathsForVisibleRows else { return } 5 let allIndexPaths = indexPaths.count 6 guard let imageView = UIImage(named: "check mark") else { return } 7 8 if closeButton.image == nil && closeButton.title == "Check all" { //全てのtable cell を選択する 9 for _ in 0 ..< allIndexPaths { 10 tableView.selectRow(at: indexPaths, animated: true, scrollPosition: .none) 11 } 12 } else if closeButton.image == nil && closeButton.title == "Unselect all" { 13 // 選択しているcellのチェックマークを全て外す(クリアにする) 14 } 15 } 16 17 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 18 return draftData.count 19 } 20 21 //各cellの要素設定(インスタンスを生成する) 22 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 23 // cellを取得する 24 guard let cell = tableView.dequeueReusableCell(withIdentifier: "draftTableCell", for: indexPath) as? CustomizedTableViewCell else { 25 return UITableViewCell() 26 } 27 28 //cellに表示する値を設定する 29 cell.titleLabel.text = draftData[indexPath.row].data()["title"] as? String 30 cell.detailLabel.text = draftData[indexPath.row].data()["detail"] as? String 31 32 cell.titleLabel.numberOfLines = 0 33 cell.detailLabel.numberOfLines = 0 34 cell.titleLabel.lineBreakMode = .byWordWrapping 35 cell.titleLabel.lineBreakMode = .byWordWrapping 36 37 return cell 38 } 39 40 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { 41 if editingStyle == .delete { 42 } 43 } 44} 45

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayabusabusash

2019/07/25 03:33

どのあたりでエラーになりますか? また、どんなエラーが出ているのか教えていただけないでしょうか?
退会済みユーザー

退会済みユーザー

2019/07/25 03:47 編集

追記・修正依頼ありがとうございます! エラーが出ているのは 2つ目のコードの6行目あたり↓ if closeButton.image == nil && closeButton.title == "Check all" { //全てのtable cell を選択する for _ in 0 ..< allIndexPaths { tableView.selectRow(at: indexPaths, animated: true, scrollPosition: .none) } の、 `tableView.selectRow(at: indexPaths, animated: true, scrollPosition: .none)` 部分です。 エラー内容は↓です。 Cannot convert value of type '[IndexPath]' to expected argument type 'IndexPath?
hayabusabusash

2019/07/25 03:50

返信ありがとうございます! みにくくて申し訳ないですが、こんな感じにしたらエラーは消えませんか? if let indexPaths = tableView.indexPathsForVisibleRows { for indexPath in indexPaths { tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none) } }
退会済みユーザー

退会済みユーザー

2019/07/25 04:57

遅くなりました! やってみたところ、エラーも出なくなった上にやりたかったことがやれるようになっていっぺんに全部解決致しました!!!! ありがとうございます!!!( ;∀;)
guest

回答2

0

indexPathsForVisibleRowsを対象に選択を行っても、「見えてる部分」しかチェックが入りませんが、大丈夫でしょうか?

1000行で試した結果を載せておきます。
イメージ説明

swift

1import UIKit 2 3class ViewController: UITableViewController { 4 5 6 7 override func viewDidLoad() { 8 super.viewDidLoad() 9 10 tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") 11 tableView.isEditing = true 12 tableView.allowsMultipleSelectionDuringEditing = true 13 } 14 15 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 16 return 1000 17 } 18 19 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 20 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 21 cell.textLabel?.text = "(indexPath.row)" 22 return cell 23 } 24 25 @IBAction func hoge(_ sender: Any) { 26 guard let indexPaths = tableView.indexPathsForVisibleRows else { return } 27 for indexPath in indexPaths { 28 tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none) 29 } 30 31 /*for row in 0..<1000 { 32 tableView.selectRow(at: IndexPath(row: row, section: 0), animated: false, scrollPosition: .none) 33 }*/ 34 } 35}

「すべて選択」を実現したいのであれば、indexPathsForVisibleRowsではなく、全データに対応するIndexPathを自分で生成し、選択を行う必要があります。
コードだとたぶん以下のようになると思います。

swift

1for row in 0..<draftData.count { 2 let indexPath = IndexPath(row: row, section: 0) 3 tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none) 4}

投稿2019/07/25 07:20

編集2019/07/25 08:57
takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2019/07/25 08:01

見えてないセルはnilですね‥。
takabosoft

2019/07/25 08:58

今回はセルへのアクセスではなく、selectRowを使った選択処理の話ですので、生成されていないCellでも大丈夫です。
fuzzball

2019/07/25 09:09

あ、ごめんなさい。完全に勘違いです!
退会済みユーザー

退会済みユーザー

2019/07/26 00:44 編集

takabosoftさん!返信が大変遅くなりましたorz 昨日ご回答下さっていた for row in 0..<draftData.count{ ... } で試したところ見えていない部分までちゃんと一括選択できて、本来やりたかった実装になりました ( ;∀;)ありがとうございます!!! (以前、for in文で <draftData.count 使った時にエラーが出て上手く行かなかったのでdraftData.countは使えないものと思い込んでおりました... :_| 追加編集で例まであげて丁寧にご解説くださり大変わかりやすかったです!ありがとうございます!!!)
fuzzball

2019/07/26 00:47

直接 draftData.count を使うのではなく tableView(tableView, numberOfRowsInSection: 0) を呼び出すほうが良いと思います。
退会済みユーザー

退会済みユーザー

2019/07/26 00:54

>fuzzballさん 不勉強で大変恐縮なのですが、差し支えなければ「 draftData.count を使うよりも tableView(tableView, numberOfRowsInSection: 0) を呼び出すほうが良い」と考えられている理由を教えていただけませんか? orz
fuzzball

2019/07/26 01:04

必要なのはセル数であって、データ数ではありません。 現在は、たまたま「セル数 == データ数」なだけです。 例えば、もし(なんらかの理由で)セル数 != draftData.count になったとき、今回の箇所も変更しないといけなくなります。
takabosoft

2019/07/26 01:32

保守性を考えたときに、って意味ですよね。 私もその方が良いと思います。 極論を言えばextension UITableViewでselectAllRow関数などを作って汎用的にうごくものにした方が使いまわしも出来て良いとは思いますが、まあ今回の本題ではないので割愛します。
退会済みユーザー

退会済みユーザー

2019/07/26 02:00

なるほど。。 ありがとうございます!
guest

0

ベストアンサー

”質問への追記・修正の依頼”をしてくださったhayabusabusashさんが書いてくださった方法を試みたところ、この質問に対して解決致しました!!!!hayabusabusashさん、ありがとうございます!!!

また、”回答”してくださった** takabosoftさんのおかげで、本来行いたかった実装まで一気に解決いたしました!丁寧な解説でわかりやすくとても助かりました!! takabosoft**さん、ありがとうございます!!!

御二方とも、本当にありがとうございます!( ;∀;)

投稿2019/07/25 05:01

編集2019/07/26 00:49
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問