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

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

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

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

Q&A

解決済

1回答

3265閲覧

Swift デリゲートで値を渡す方法

torkia

総合スコア24

Swift

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

0グッド

0クリップ

投稿2018/09/08 07:02

編集2018/09/10 09:20

画面遷移で、遷移元のvcにデリゲートを使って値を渡そうとしているのですが、NavigationBarのbackボタンからテーブルビューのあるSecondViewControllerに戻るときに値が渡せなくて困っております。
わかる方がいらっしゃいましたら、教えて頂けないでしょうか。
よろしくお願い致します。

やりたいこと

設定画面で設定した値によって、コンテンツVCすべてにその設定値を共有してもらって、画面レイアウトや音設定を再描画させたいです。

● 現在の状況
デリゲートを使って設定画面から戻る遷移では値を渡し、コンテンツVC内ではページ移動の際に値を渡すことができているのですが、コンテンツVCのページから2枚目のテーブルビューのあるVC(SecondViewController)に戻ると設定画面で変更した値が初期値にリセットされてしまいます。
初期値は1枚目のテーブルビューがあるVC(ViewController)でセットしています。

● 試してみたこと
Storyboardで埋め込んだNavigationControllerのbackボタンから戻っているので、テーブルビューに戻るときに渡したい値をどこでセットすればいいのか分からず、ページ管理VCやコンテンツVCなどのviewWillDissappearなどに記述してみたのですが、うまくいきませんでした。
記述場所やコード記述が間違っているのかと思うのですが・・・

イメージ説明
(使用Version Swift3)

import Foundation protocol testDelegate: class { var soundSetting:Int! { get set } var soundRate:Float! { get set } func test1() func test2(soundSetting: Int) }
import UIKit class SecondViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { let sectionTitle = ["(略)"] // セルに表示する配列 let section0 = ["(略)"] // セルに表示する配列 @IBOutlet var secondTableView: UITableView! weak var testdelegate: testDelegate? // シーン移動の際に渡される値 var selectedVC: Int! var soundSetting:Int! var soundRate:Float! let currentIndex:Int? = nil // 選択されたセルを覚える変数 var chosenCell: Int! override func viewDidLoad() { super.viewDidLoad() secondTableView.delegate = self secondTableView.dataSource = self } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if testdelegate?.soundSetting != nil { soundSetting = testdelegate?.soundSetting soundRate = testdelegate?.soundRate } } (略) // PageViewControllerへ遷移するための準備(セグエ遷移) override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let pageViewController = segue.destination as? PageViewController { (略) } }
import UIKit class PageViewController: UIPageViewController, UIPageViewControllerDataSource,UIPageViewControllerDelegate { weak var testdelegate: testDelegate? // ナビゲーションバーのNext/Backボタン @IBOutlet weak var navNextButton: UIBarButtonItem! @IBOutlet weak var navBackButton: UIBarButtonItem! // シーン移動の際に渡される値 var selectedVC:Int = 0 // viewControllerで押されたセルのindex var selectedSVC: Int = 0 // SecondViewControllerで押されたセルのindex var arrayLength: Int = 0 // SVCの配列の要素数が作成ページ数となる var soundSetting: Int! // 設定画面で設定する音設定 var soundRate:Float! // 設定画面で設定する音速度 var pageIndex: Int = 0 // コンテンツVC作成時に各vcにセットするindex // ページングするviewControllerを格納する配列 var contentVCs = [UIViewController]() // delegateメソッドで取得する値 var pendingIndex: Int = 0 var previousIndex: Int = 0 var currentIndex: Int = 0 // 現在indexのプロパティ override func viewDidLoad() { super.viewDidLoad() dataSource = self delegate = self // コンテンツViewControllerを作成 for index in 0..<arrayLength { let contentVC = storyboard?.instantiateViewController(withIdentifier: "PageContentViewController") as! PageContentViewController contentVC.pageIndex = index contentVC.selectedSVC = selectedSVC contentVC.selectedVC = selectedVC contentVC.soundSetting = soundSetting contentVC.soundRate = soundRate contentVCs.append(contentVC) } self.setViewControllers([contentVCs[selectedSVC]], direction: .forward, animated: true, completion: nil) // テーブルビューから遷移したらセルのindexを代入 currentIndex = selectedSV } // viewDidLoad()を閉じる override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) /*// デリゲートの設定(試して失敗したコード) let secVC = storyboard!.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController secVC.testdelegate?.soundSetting = soundSetting secVC.testdelegate?.soundRate = soundRate */ } // 設定画面へセグエで遷移 (SecondSettingViewControllerへ) override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let secondSettingVC = segue.destination as? SecondSettingViewController { secondSettingVC.soundSetting = soundSetting secondSettingVC.soundRate = soundRate let currentVC = contentVCs[currentIndex] secondSettingVC.testdelegate = currentVC as? testDelegate } } (略) }
import UIKit import AVFoundation class PageContentViewController: UIViewController, AVAudioPlayerDelegate, testDelegate { // デリゲートの型を設定 weak var testdelegate: testDelegate? //シーン移動の際に設定されるデータ var pageIndex:Int = 0 var selectedVC:Int = 0 var selectedSVC:Int = 0 var arrayLength:Int = 0 var soundSetting:Int! var soundRate:Float! override func viewDidLoad() { super.viewDidLoad() (略) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) /*// デリゲートの設定(試して失敗したコード) let secVC = storyboard!.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController secVC.testdelegate?.soundSetting = soundSetting secVC.testdelegate?.soundRate = soundRate */ } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) test1() test2(soundSetting: soundSetting) } // デリゲートメソッド func test1() { // soundSettingとRateのラベルの表示を更新する soundSettingLabel.text = "soundSetting: (soundSetting)" soundRateLabel.text = "soundRate: (soundRate)" } func test2(soundSetting: Int) { // 再生ボタンを非表示にし、viewの背景色を赤にする if soundSetting == 0 { for i in 0..<soundArray.count { self.view.backgroundColor = UIColor.red soundButtons[i].isHidden = true } } if soundSetting == 1 { // 再生ボタンを表示させ、viewの背景色を茶色にする for i in 0..<soundArray.count { self.view.backgroundColor = UIColor.brown soundButtons[i].isHidden = false } } } (略) }

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

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

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

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

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

fuzzball

2018/09/10 07:25

もう少し簡潔に書けないでしょうか?
torkia

2018/09/10 09:23

ご指摘ありがとうございます。削除・編集致しました。
guest

回答1

0

ベストアンサー

ざっとしか読んでいませんが、アプリ全体のVCに対する設定なのであれば、delegateで受け渡しするのではなく、UserDefaultsに保存した方がいいと思います。

delegate

これ、delegateって名前なだけで、単に設定を共有しているだけですかね?
SoundSettingsクラスをシングルトンで作った方がいいのでは?

失敗コード

失敗している原因は、インスタンスを新たに生成しているからです。既存のインスタンスに対してアクセスして下さい。

デリゲート云々は全く関係なく、ViewController間の値の受け渡しの問題です。
この手の質問はteratailでもよく見かけますし、ググれば記事も見つかるでしょう。

投稿2018/09/10 07:27

編集2018/09/13 01:40
fuzzball

総合スコア16731

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

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

torkia

2018/09/12 15:55 編集

ご回答ありがとうございます。 >> これ、delegateって名前なだけで、単に設定を共有しているだけですかね? そういうことになるんでしょうか?アプリによくある設定画面のようなものですが・・・ プロトコルにデリゲートメソッドも付加していますが、プロパティさえ共有できればよいとも思えます。 試行錯誤の末、アドバイス頂いたUserDefaultsやシングルトン、AppDelegateなどでは値渡し(共有)はできたのですが、delegateではまだできていません。実際にやってみて、使用するならUserDefaults・シングルトン・AppDelegateのどれかだと思いましたが、delegateがいまいち理解できず、勉強のためにも克服しておきたいという思いもあります。 参考になりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問