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

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

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

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

Q&A

解決済

1回答

458閲覧

swift UserDafaultsで保存したデータを他のViewControllerに持ってくる

globalplus

総合スコア119

Swift

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

0グッド

0クリップ

投稿2018/10/11 09:02

SecondViewControllerにUISliderを置いてそれによって音量を変更出来、FirstViewControllerにあるアラームの音量に反映させたいと考えています。その為にユーザが設定した音量(UISliderの値)をUserDafaultsを使ってFirstViewControllerに持って来たんですがエラー(Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0))に遭遇したため質問させて頂きます。
理想はUISliderで入力した数値をアラームの音量として使いたいです。(iPhoneの設定->サウンドと触覚->着信音と通知音のSliderが理想です。ライブラリは見つからなかった泣)
お手数ですがどうかよろしくお願いします。

FirstViewController

1import UIKit 2import AVFoundation 3 4class FirstViewController: UIViewController, AVAudioPlayerDelegate, UITableViewDelegate, UITableViewDataSource{ 5 6 let TODO = ["a", "b", "c", "d"] 7 //アラームのリストです 8 let volumeSlider = UISlider() as! SecondViewController 9 //Cast from 'UISlider' to unrelated type 'SecondViewController' always failsという警告が出ています。自分なりに書いてみましたがこれがダメなんでしょうか? 10 var volume: Float = 0 11 var counter = 0 12 var timer = Timer() 13 var startTime:Double = 0.0 14 var audioPlayer: AVAudioPlayer! 15 @IBOutlet weak var tableView: UITableView! 16 17 @IBAction func firstSwitch(_ sender: UISwitch) 18 { 19 if (sender).isOn 20 { 21 timer = Timer.scheduledTimer(withTimeInterval: 1 * 1, repeats: false, block: { timer in 22 23 self.audioPlayer.volume = self.volumeSlider.value(forKey: "DateStore") as! Float 24 //自分で書いてみました 25 26 self.audioPlayer.play() 27 28 self.audioPlayer.numberOfLoops = -1 29 print(self.audioPlayer.isPlaying) 30 }) 31 }else{ 32 timer.invalidate() 33 print("switch1stopped") 34 self.audioPlayer.stop() 35 } 36 }

SecondViewController

1import UIKit 2import AVFoundation 3 4class SecondViewController: UIViewController { 5 6 var audioPlayer: AVAudioPlayer! 7 8 let userDefaults = UserDefaults.standard 9 let str = Float() 10 @IBOutlet weak var volumeSlider: UISlider! 11 @IBOutlet weak var volumeLabel: UILabel! 12 @IBAction func volumeChange(_ sender: UISlider) 13 { 14 volumeLabel.text = String(Int(sender.value)) 15 volumeSlider.value = sender.value 16 audioPlayer.volume = volumeSlider.value 17 userDefaults.set(str, forKey: "DataStore") 18 audioPlayer.play() 19 } 20 21 override func prepare(for segue: UIStoryboardSegue, sender: Any?) 22 { 23 if segue.identifier == "endSetting" 24 { 25 let SecondViewController = segue.destination as! SecondViewController 26 SecondViewController.volume = volumeSlider.value 27 } 28 }//値渡しの方法が分からなかったのでsegueをviewcontrollerごと繋いでみました

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

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

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

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

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

guest

回答1

0

ベストアンサー

おそらく下記の部分を変更すればいけると思います。

変更前

self.audioPlayer.volume = self.volumeSlider.value(forKey: "DateStore") as! Float

変更後

let userDefaults = UserDefaults.standard self.audioPlayer.volume = userDefaults.object(forKey: "DateStore") as! Float

あとは、UserDefaultsはAny?で返ってくるので、letで定義した方が安全かなとは思いました。

let userDefaults = UserDefaults.standard if let volume:Float = userDefaults.object(forKey: "DateStore") as? Float{ self.audioPlayer.volume = volume }

投稿2018/10/11 14:44

TakuyaEndo

総合スコア16

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

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

globalplus

2018/10/12 01:24

ご回答ありがとうございます。試した結果アラームは鳴るようになったのですがUISliderで入力した値ではなくmp3ファイルそのものの音量で流れてしまっています。自分でself.audioPlayer.volume = volumeの所が self.audioPlayer.volume = volumeSlider(UISliderです).volumeかなと思い、でやってみたのですが他のviewcontrollerで宣言したオブジェクトを今のviewcontrollerで使う方法を知らないので困っています。エラーログはUse of unresolved identifier 'volumeSlider'となっています。 ご回答頂けたら嬉しいです。 ちなみにどうでも良いですが僕の本名も拓也です笑
TakuyaEndo

2018/10/12 04:47

うーん。他のviewControllerから値を取得するというのは基本やらないです。 viewContoller内で完結する処理を書くのが理想で 値を渡すとしたら、init処理時に指定するか、realmやuserDefaultsなどで取得するとか、クロージャ使うとか、何を実現したいかによって色々な方法があります。 今回の場合UserDefaultsで問題なくできると思いますよ。もう少し詳しく見て欲しいのですが、 audioPlayerのvolumeは0.0 - 1.0 なので、UISliderで設定している値もこの値になっていますか? https://developer.apple.com/documentation/avfoundation/avaudioplayer/1389330-volume
TakuyaEndo

2018/10/12 04:50 編集

``` if let volume:Float = userDefaults.object(forKey: "DateStore") as? Float{ debugPrint(volume) self.audioPlayer.volume = volume } ```
globalplus

2018/10/12 05:33

UISliderの値を0-1に変更しましたが音量は同じです。 もしかしたらUISliderから指を離した時に音楽が止まるコードを書いていないせいですかね?(どうやって書いたら良いか分からないので放置してました。なので毎回確認する時は音楽全て(16秒)を最後まで聞いてますアホなのは分かってます)
TakuyaEndo

2018/10/12 08:41

class FirstViewController { NotificationCenter.default.addObserver(self, selector: #selector(volumeChange), name: "test", object: nil) func volumeChange() -> Void { self.audioPlayer.start() self.audioPlayer.stop() } } class SecondViewController{ NotificationCenter.default.post(name:"test", object: nil) } それであればNotificationCenterを使えばできるはずです。
TakuyaEndo

2018/10/12 08:45

今更ですが、 FirstとSecondでControllerを分けたことによって実現したいこと が僕自身いまいち理解できていないので場当たり的なアドバイスになっているかもです。
globalplus

2018/10/13 07:35

わかりやすいご回答本当にありがとうございます。 実現したい事はSecondにある音量バー(UISlider)で設定した音量をFirstのアラームが鳴った時の音量として使いたいです(iPhoneの設定にある音量設定と全く同じ仕様です) 上記のNotificationcenter実装してみたのですが以前うまくいかずです、、 思ったのがそもそもUISliderで入力した値は音量の値ですよっていうコードかいてないからですかね? UISliderは音量の他に拡大とか色々使い道があると思うので今回は音量で使うよ!っていうコード(宣言?)みたいなものを書いていないからかなと思いますがどうでしょうか?
TakuyaEndo

2018/10/15 14:57

もう一度ソース読んだのですがここかもです @IBAction func volumeChange(_ sender: UISlider) { volumeLabel.text = String(Int(sender.value)) volumeSlider.value = sender.value audioPlayer.volume = volumeSlider.value userDefaults.set(str, forKey: "DataStore") audioPlayer.play() } これだとstrに何もセットされていないので @IBAction func volumeChange(_ sender: UISlider) { str = sender.value userDefaults.set(str, forKey: "DataStore") } とかにしないと行けないかと。
TakuyaEndo

2018/10/15 14:59

> 思ったのがそもそもUISliderで入力した値は音量の値ですよっていうコードかいてないからですかね? swiftは基本的に型があっていれば、「音量の値ですよ」とは言わなくていいです。 audioPlayer.volumeはFloatで間違い無いので、その可能性は低いかと。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問