🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
TableView

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

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

1回答

2215閲覧

TableViewで複数選択したものを全て取得する方法

LATA-apple

総合スコア3

TableView

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

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2021/03/08 04:43

解決したいこと

TableViewで複数選択可能にして、選択された値全てを取得して次の画面に値渡しをしたいのですが、Buildしてみると複数選択したのにもかかわらず、値が一つしか渡されませんでした。
選択された全ての値を取得(値渡し)する方法はありますでしょうか?
独学でプログラミングを始めて1ヶ月ほどなのでわかりやすく解決方法を教えてくださると嬉しいです。

発生している問題・エラー

エラーはなし

該当するソースコード

swift

1import UIKit 2 3class SupportForm03ViewController: UIViewController , UITableViewDelegate, UITableViewDataSource { 4 @IBOutlet var OS: UITableView! 5 @IBOutlet var NextPage: UIButton! 6 7 var rowListArray = [Int]() 8 var itemListArray = [Int]() 9 var sortArray = [Int]() 10 11 var NameSend = "" 12 var EmailSend = "" 13 var ProductSend = "" 14 var OSSend = "" 15 var ContentsSend = "" 16 var SolutionSend = "" 17 18 19 var ALLOS = ["macOS 11.2.2","macOS 11.2.1", "macOS 11.2", "macOS 11.1", "macOS 11.0.1", "macOS 11.0.1","macOS 10.15.7","macOS 10.15.6","macOS 10.15.6","macOS 10.15.6","macOS 10.15.5","macOS 10.15.5","macOS 10.15.4","macOS 10.15.4","macOS 10.15.3","macOS 10.15.2","macOS 10.15.1","macOS 10.15.0","macOS 10.15.0","macOS 10.15.0", 20 "iPadOS14.4","iPadOS14.3","iPadOS14.2.1","iPadOS14.2","iPadOS14.1","iPadOS14.0.1","iPadOS14","iPadOS13.7","iPadOS13.6.1","iPadOS13.6","iPadOS13.5.1","iPadOS13.5","iPadOS13.4.1","iPadOS13.4","iPadOS13.3.1","iPadOS13.3","iPadOS13.2.3","iPadOS13.2.2","iPadOS13.2","iPadOS13.1.3","iPadOS13.1.2","iPadOS13.1.1","iPadOS13.1", 21 "iOS14.4","iOS14.3","iOS14.2.1","iOS14.2","iOS14.1","iOS14.0.1","iOS14","iOS13.7","iOS13.6.1","iOS13.6","iOS13.5.1","iOS13.5","iOS13.4.1","iOS13.4","iOS13.3.1","iOS13.3","iOS13.2.3","iOS13.2.2","iOS13.2","iOS13.1.3","iOS13.1.2","iOS13.1.1","iOS13.1","iOS13", 22 "watchOS7.3.1","watchOS7.3","watchOS7.2","watchOS7.1","watchOS7.0.3","watchOS7.0.2","watchOS7.0.1","watchOS7","watchOS6.2.8","watchOS6.2.6","watchOS6.2.5","watchOS6.2.1","watchOS6.2","watchOS6.1.3","watchOS6.1.2","watchOS6.1.1","watchOS6.1","watchOS6.0.1","watchOS6", 23 "3.3.1","3.5.1","3.7.2","6.3.2","6.7.8","6.8.8","1A661","1A673","1A691","2A364","2B584","2B488","2C54","2D15","2D27","3A283", 24 "その他(不具合内容の欄で入力お願いします。)"] 25 26 27 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 28 return ALLOS.count 29 } 30 31 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ 32 let cell = UITableViewCell() 33 cell.backgroundColor = UIColor.clear 34 // セルの選択時の背景色を消す 35 cell.selectionStyle = UITableViewCell.SelectionStyle.none 36 cell.textLabel?.text = ALLOS[indexPath.row] 37 // セルの選択状況の判定 38 if (rowListArray.contains(indexPath.row)){ 39 cell.accessoryType = .checkmark 40 }else{ 41 cell.accessoryType = .none 42 } 43 return cell 44 } 45 46 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ 47 let cell = tableView.cellForRow(at: indexPath) 48 // 選択したセルにチェックマークが無い場合 49 if(cell?.accessoryType == UITableViewCell.AccessoryType.none){ 50 cell?.accessoryType = .checkmark 51 self.rowListArray.append(indexPath.row) 52 }else{ 53 // 選択したセルにチェックマークがある場合 54 cell?.accessoryType = .none 55 let listNumber = rowListArray.filter ({ (n:Int) -> Bool in 56 if n != indexPath.row{ 57 return true 58 }else{ 59 return false 60 }}) 61 rowListArray = listNumber 62 } 63 // 配列を昇順で並び替え、 64 // 都道府県コードに変換する。 65 sortArray = rowListArray.sorted{$0 < $1} 66 itemListArray = sortArray.map{$0 + 1} 67 print("OS(itemListArray)") 68 } 69 70 override func viewDidLoad() { 71 super.viewDidLoad() 72 OS.allowsMultipleSelection = true 73 74 // Do any additional setup after loading the view. 75 } 76 77 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 78 let vc = segue.destination as! SupportForm04ViewController 79 vc.NameSend = NameSend 80 vc.EmailSend = EmailSend 81 vc.ProductSend = ProductSend 82 if let row = OS.indexPathForSelectedRow?.row { 83 vc.OSSend = ALLOS[row] 84 } 85 } 86 87 /* 88 // MARK: - Navigation 89 90 // In a storyboard-based application, you will often want to do a little preparation before navigation 91 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 92 // Get the new view controller using segue.destination. 93 // Pass the selected object to the new view controller. 94 } 95 */ 96 97}

自分で試したこと

検索してみましたが複数の値を渡す方法が見つからず、現在に至ります。

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

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

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

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

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

guest

回答1

0

ベストアンサー

indexPathForSelectedRow は UITableView で管理している「選択された状態」の IndexPath を返すメソッドです。

今回の場合、そうではなくてご自身で管理されている配列を渡せば良さそうなので

Swift

1 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 2 let vc = segue.destination as! SupportForm04ViewController 3 vc.NameSend = NameSend 4 vc.EmailSend = EmailSend 5 vc.ProductSend = ProductSend 6 7 // 選択された row だけわたすのであれば 8 // row の型は [Int] 9 vc.row = rowListArray 10 11 // 機種名を渡すのであれば 12 // selectedOS の型は [String] 13 vc.selectedOS = rowListArray.map { ALLOS[$0] } 14 }

みたいな具合にすれば良いかと思います。

もちろん、rowなりselectedOSは遷移先のクラスにあらかじめ準備しておく必要があります。


ところで、プロパティ名やクラス名の付け方が、Swift の慣習と異なり混乱してしまいます。

基本的に

  • プロパティ名は小文字で始める(NameSend ではなくて nameSendなど)
  • UI部品に関するプロパティ名には、部品名が連想できるような名前を含める(OSではなく、OSTableViewなど。これもイマイチですが...)

などに従った方がいいと思います。

--

ちなみに、選択状態を確かめるロジックも少しおかしい感じがします。
このように書き換えてみてはいかがでしょうか。

Swift

1 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ 2 // indexPath に選択された Cell に対応する番号が入っている 3 4 // rowListArray に選択した indexPath.row があるか調べる 5 if let index = rowListArray.firstIndex(of: indexPath.row) { 6 // あれば削除する 7 rowListArray.remove(at: index) 8 } else { 9 // なければ追加する 10 rowListArray.append(indexPath.row) 11 } 12 13 tableView.reloadRows(at: [indexPath], with: .automatic) 14 15 // 配列を昇順で並び替え、 16 // 都道府県コードに変換する。 17 sortArray = rowListArray.sorted{$0 < $1} 18 itemListArray = sortArray.map{$0 + 1} 19 print("OS(itemListArray)") 20 }

cellForRow(at:)は、基本的に Visible (表示されている範囲)、もっと性格に言うと dequeue されている範囲のセルしか調べることができませんし、基本的に使うことは推奨されていません。

cellForRow(at:)を使わなくとも、rowListArrayに選択済みのセル番号を管理しているので、それを使えば簡潔に済むかと思いますし、想定外の動作が起きることもありません。

表示の変更も、reloadRows(at:with:) あるいは reloadData() を使うといいかと思います。


加えて、TableViewCell の生成方法も一般的な方法と異なっています。

Swift

1 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ 2 let cell = UITableViewCell()

と毎回 UITableViewCell のインスタンスを作っていますが、基本的には UITableViewCell は使い回すものなので、そのような方法に書き換えた方が良いかと思います。

- UITableViewCellの再利用を知る

基本的なコードについては

TableViewCell をご自身でデザインするなら、関連する資料をご参照いただければと思います。

投稿2021/03/08 06:09

TsukubaDepot

総合スコア5086

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問