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

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

詳細はこちら
JSON

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

Xcode

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

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

1回答

1127閲覧

TableViewCellにAccessoryViewで追加したUISwitchの動作をセルごとに記述したい。

zepi1395

総合スコア2

JSON

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

Xcode

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

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2021/01/24 04:41

前提・実現したいこと

swiftでトレーニングメニューを表示するアプリを作っています。
ViewTableCellにUISwitchをAccessoryViewで追加しています。
Switchをonにすると該当の行の種目名と紐づいたfavos[i].favに1が代入されます。offにすると0です。変数はjsonファイルを読み書きし保存しています。
画像のページから前に戻り,またこのページを生成した時その変数(favos[i].fav)が0か1かによって各セルのUISwitchのon,offを変えて表示したいです。

発生している問題・エラーメッセージ

どのSwitchが何行目のセルに属しているのか判別できず,すべてのSwitchがonになってしまいます。
Switchのon,offを個別に設定する方法を教えて欲しいです。
イメージ説明

該当のソースコード

swift

1/*TableViewCellの描画部分*/ 2 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 3 let cell: UITableViewCell! = tableView.dequeueReusableCell(withIdentifier: "events") 4 let item = items.filter{$0.part == tappedPart}[indexPath.row]//押されたボタンの部位の配列の中身をitemに代入する。 5 cell.textLabel?.text=item.name 6 let Switch = UISwitch() 7 cell.accessoryView = Switch 8 Switch.tag = indexPath.row 9 Switch.addTarget(self, action: #selector(pushedSwitch(_:)), for: UIControl.Event.valueChanged) 10 11 for i in 0..<favos.count{ 12 if(favos[i].fav == 1){ 13 Switch.isOn = true 14 } 15 } 16 return cell 17 } 18/*Switchが押された時の処理*/ 19 @objc func pushedSwitch(_ sender: UISwitch){ 20 //print("indexPathRow") 21 //print(sender.isOn) 22 //print(sender.tag) 23 let item = items.filter{$0.part == tappedPart}[sender.tag] 24 if (sender.isOn == true){ 25 print(item.name) 26 for i in 0..<favos.count{ 27 print(favos[i].name) 28 if(favos[i].name == item.name){ 29 favos[i].fav = 1 30 print(favos[i]) 31 break 32 } 33 if(i == favos.count - 1){ 34 let name = item.name 35 favos.append(Favorite(name: name ,fav: 1)) 36 print(favos) 37 } 38 } 39 }else{ 40 for i in 0..<favos.count{ 41 if(favos[i].name == item.name){ 42 favos[i].fav = 0 43 print(favos[i]) 44 } 45 } 46 } 47 48 } 49/*ファイルの保存部分*/ 50 override func viewWillDisappear(_ animated: Bool) { 51 super.viewWillDisappear(animated) 52 guard let url = Bundle.main.url(forResource: "favorite", withExtension: "json") else { fatalError("ファイルが見つかりません") } 53 guard let data = try? JSONEncoder().encode(favos) else{ 54 fatalError("ファイル読み込みエラー") 55 } 56 print(data) 57 do{ 58 try data.write(to: url) 59 }catch{ 60 fatalError("ファイル書き込みエラー") 61 } 62 }

補足情報(FW/ツールのバージョンなど)

Xcode ver.12.3
iOS 13.5
iPhone 12 Pro Max
ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

全体のデータ構造が見えないのですが、「スイッチの状態 = 実施したトレーニングの種類」だと思いますので、item に相当するクラスでトレーニングの有無を管理させれば良いのではないでしょうか。

下記の例だと、AccessoryView に追加する UISwitchtagindexPath.row を入れてますが、Cell そのもののカスタムクラスを作り、その中で個別にクラスを保持し、そこでスイッチの状態を監視させるという方法もありますし、その場合は indexPath.row に依存しなくなるのでもっと良いかもしれません。

ここでは UserDefault でデータの永続化を行っていますし、その都合上構造体を使っていますが、その部分はご自身の設計に合わせて変更していただければと思います。

あくまでも一例ということで。

Swift

1import UIKit 2 3// スイッチの状態もプロパティとして持たせる 4struct Item: Codable { 5 var name: String 6 var isOn = false 7 8 init(name: String) { 9 self.name = name 10 } 11} 12 13class ViewController: UIViewController { 14 // ここでは UserDefaults に逐次保存しているだけ。 15 var items: [Item] { 16 set { 17 UserDefaults.standard.setEncoded(newValue, forKey: "array") 18 } 19 20 get { 21 UserDefaults.standard.decodedObject([Item].self, forKey: "array") ?? [] 22 } 23 } 24 25 @IBOutlet weak var tableView: UITableView! { 26 didSet { 27 tableView.dataSource = self 28 } 29 } 30 31 override func viewDidLoad() { 32 super.viewDidLoad() 33 34 // items が空であれば新規作成 35 if items.isEmpty { 36 items = (1...30).map { Item(name: String($0)) } 37 } 38 } 39} 40 41extension ViewController: UITableViewDataSource { 42 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 43 return items.count 44 } 45 46 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 47 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 48 49 cell.textLabel?.text = items[indexPath.row].name 50 51 let sw = UISwitch() 52 sw.isOn = items[indexPath.row].isOn 53 sw.addTarget(self, action: #selector(switchChanged(_:)), for: .valueChanged) 54 sw.tag = indexPath.row 55 56 cell.accessoryView = sw 57 58 return cell 59 } 60 61 // Switch につけた tag で管理する 62 @objc func switchChanged(_ sender: UISwitch) { 63 items[sender.tag].isOn = sender.isOn 64 } 65} 66 67//https://qiita.com/masakihori/items/7a0ed9d109800d714c0b 68extension UserDefaults { 69 func setEncoded<T: Encodable>(_ value: T, forKey key: String) { 70 guard let data = try? JSONEncoder().encode(value) else { 71 print("Can not Encode to JSON.") 72 return 73 } 74 75 set(data, forKey: key) 76 } 77 78 func decodedObject<T: Decodable>(_ type: T.Type, forKey key: String) -> T? { 79 guard let data = data(forKey: key) else { 80 return nil 81 } 82 83 return try? JSONDecoder().decode(type, from: data) 84 } 85}

投稿2021/01/24 06:07

TsukubaDepot

総合スコア5086

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

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

zepi1395

2021/01/28 13:51

返信が遅くなり大変申し訳ありません。 ご教授いただいたコードを参考に試行してみたところ、 前のページに戻っても正常に描画されるようになりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問