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

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

詳細はこちら
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

iOS

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

Xcode

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

Swift

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

Q&A

解決済

1回答

864閲覧

複数選択したTableViewのCellのデータを計算した結果を表示したい

Jonny_dayo

総合スコア48

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

iOS

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

Xcode

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

Swift

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

0グッド

0クリップ

投稿2019/10/02 01:35

編集2019/10/02 09:25

前提・実現したいこと

TableViewにJSONデータを表示しています。
名前・数量・単位・値段を表示しているのですが、その中の値段だけを計算して原価計と書いてる場所に結果を表示させたいです。
イメージ説明

cell選択時のコード

Swift

1 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 2 print("select - (indexPath)") 3 let cell = tableView.cellForRow(at:indexPath) 4 5 cell?.accessoryType = .checkmark 6 //まずgenkaTotalにpriceArrayを表示させる? 7         //priceArrayをInt型に変える 8      //選択したcellのpriceArrayをgenkaTotalに足していく 9 } 10 11 func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { 12 print("deselect - (indexPath)") 13 let cell = tableView.cellForRow(at:indexPath) 14 15 cell?.accessoryType = .none 16          //priceArrayをInt型に変える 17 //選択したcellのpriceArrayをgenkaTotalから引いていく 18 }

JSONデータ

Swift

1 func getData(){ 2 let text = "https://script.google.com/macros/s/AKfycbw1IzuulWfaxTtgsNS9Yi5iUNeBqBHy1XC-wV0IOBiAjpzsw98/exec" 3 let url = text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) 4 AF.request(url!, method: .get, parameters: nil, encoding: JSONEncoding.default).responseJSON { (response) in 5 switch response.result{ 6 case .success: 7 // 通信成功時 8 guard let data = response.data else { 9 return 10 } 11 12 do { 13 let googleData = try JSONDecoder().decode([GoogleData].self, from: response.data!) 14 15 googleData.forEach { item in 16 self.nameArray.append(item.name) 17 self.amountArray.append("(item.amount)") 18 self.taniArray.append(item.tani) 19 self.priceArray.append("(item.price)") 20 } 21 } catch let error { 22 // JSON -> GoogleData にデコード失敗 23 print(error) 24 } 25 case .failure(let error): 26 // 通信の失敗 27 print(error) 28 } 29 self.tableView.reloadData() 30 } 31 32 }

試したこと

原価計に文字を表示させたかったので、

genkaTotal.text = cell.priceArray[indexPath].text
と書いてみたのですが、

Value of type 'UITableViewCell?' has no member 'priceArray'

と出てしまいました。配列を取り出して、Int型に変換する方法がわかりません…
変換できたらそれをselectedで判断して合計値出すのかな?と思ってますが合ってるのでしょうか…

ツールのバージョン

Xcode : Version 11.0
Swift : Apple Swift version 5.1

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

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

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

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

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

t_obara

2019/10/02 03:20

cellではなく、selfなのでは?
Jonny_dayo

2019/10/02 03:25

確かに!?と思って、genkaTotal.text = self.priceArray[indexPath].textとしてみたのですが、 Cannot subscript a value of type '[String]' with an argument of type 'IndexPath' と出てしまいました…
t_obara

2019/10/02 03:50

それはちょっと調べれば出てくるでしょう。indexPathの扱いは基本です。
Jonny_dayo

2019/10/02 04:06

あっあっ! genkaTotal.text = self.priceArray[indexPath.row]ですね!!! ありがとうございます!! とりあえず選択したcellの値段を表示することができました!助かりましたありがとうございます!
guest

回答1

0

ベストアンサー

UITableView自体の複数選択機能をオンにしているんですよね?

だったら
UITableViewのindexPathsForSelectedRowsを使えば、選択しているセルのIndexPath一覧が取れますので、
選択状態が変わったタイミングで、毎回合計値を算出しなおせばOKです。

メンバー変数に合計値を持っておいて、セルのタップによってその合計値を足したり減らしたりするのは、整数だったらまだいいですが、小数などでは誤差がでるので、辞めたほうがいいです。毎回合計値を求める方がたぶん安全です。

また、おそらくセルの数を増やしてスクロールすると、チェックマークとセルの選択が一致しない可能性がありますので、以下のようなコードで選択状態とチェックマークを同期させる必要がありそうです。

swift

1 func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 2 cell.accessoryType = cell.isSelected ? .checkmark : .none 3 }

ちなみにアクセサリータイプで自分でチェックマークを設定しなくても、標準機能としてチェックマークを出すこともできます。
参考:
How to select multiple rows in UITableView in edit mode?


以下、本題とは関係ありませんが、一つの情報は構造体やクラスにまとめるべきです。
例えば「人」の情報として名前と年齢があり、複数人の情報を保持したい場合、
質問者さんは

swift

1var name: [String] 2var age: [Int]

のように情報を保持していますが、

swift

1struct Person { 2 var name: String 3 var age: Int 4} 5var persons: [Person]

のように人構造体(または人クラス)の配列として保持するべきです。
この方が構造化されていて人間的に理解しやすいですし後から1人分のデータを取り回しやすい形になっているので、おすすめです。

そもそも[GoogleData]としてパースしているのでしたら、そのまま[GoogleData]型のままメンバーに保持しても良いのでは?とも思います。

投稿2019/10/02 05:33

編集2019/10/02 06:15
takabosoft

総合スコア8356

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

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

Jonny_dayo

2019/10/02 07:50

takabosoft様 回答ありがとうございます! 共有頂いたURLを元に左側にチェックを付けようとしたところ、側はできたのですが肝心のマークが出てこなくて、苦戦しております… が、selectされたかどうかの状態はprintで確認できているので、これも上記で記載頂いたindexPathsForSelectedRowsを使って合計を求めていく感じでしょうか?
takabosoft

2019/10/02 08:16

> 側はできたのですが 側ってなんでしょう? > indexPathsForSelectedRowsを使って合計を求めていく感じでしょうか? そうです。
Jonny_dayo

2019/10/02 09:26

写真を更新させて頂いたのですが、左側に丸があるけど押してもチェックマーク自体は出てこない状況です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問