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

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

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

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

Swift

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

Q&A

解決済

1回答

1152閲覧

別画面のTextFieldに入力した内容をNavigationBarに表示させる

rikkachan

総合スコア16

Xcode

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

Swift

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

0グッド

0クリップ

投稿2019/01/01 16:38

画面BのTextFieldに入力した文字列を画面AのNavigationBarno真ん中に表示させたいのですがうまくいかなくて困っています。
エラーは出ていないのですが、Buildすると画面AのNavigationBar上に置いてある歯車のImageが消えて、画面Bから持って来たいと思っている文字列も表示されません。

前提

画面A
NavigationControllerの右側に歯車のImageがあります。
画面Bから持ってきた文字列を表示させようと思い、viewDidLoadの中に以下のコードを追記しました。

Swift

1// リスト名 2  guard let obj = UserDefaults.standard.object(forKey: "listName")else{ 3 return 4 } 5 self.navigationItem.title = obj as? String

画面B
TextFieldだけが置いてあるシンプルな画面で,
NavigationBar右側にある保存ボタンをタップすると
textFiledに入力された内容がUserDefaultに保存されます。

Swift

1// 設定内容をUserDefaultsに保存する 2 @IBAction func saveListName(_ sender: Any) { 3 let writtenListName = listNameTextFiled.text! as String 4 let defaults = UserDefaults.standard 5 defaults.set(writtenListName,forKey:"listName") 6 view.endEditing(true) 7 } 8

その他の情報
NavigationControllerを使用しています。

よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

UserDefaults.standard.object()としていますが、
今はUserDefaults.standard.string(forKey: "")を使えば良いはずです。
また、今回は不要ですが、もし何か(例えばAny)とかをキャストする時には
as?ではなく、as!としないといけないですよ。

そして、さらにlet defaults = UserDefaults.standardは不要で、
UserDefaults.standard.set(writtenListName,forKey:"listName")
とした方が、余計なインスタンス作らず済みます。

さらにStoryboardでNavigationControllerをEmbed inで作成した場合は
self.title = で表示されるはずです。
つまり
self.title = UserDefaults.standard.string(forKey: "
")
とすれば良いはずです。
最後に、override func viewDidAppear() {}の中に書くことが大事です。
理由は戻ってきた時に毎回ビューが表示されように描出し直さないといけないからです。

ごちゃごちゃ書いて済みません。
要約すると、きちんと保存できているなら、

swift

1override func viewDidAppear() { 2 self.title = UserDefaults.standard.string(forKey: "******") 3}

を表示したいViewに追加すれば解決するはずです。

投稿2019/01/01 16:43

編集2019/01/01 16:51
hameji001

総合スコア639

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

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

rikkachan

2019/01/01 17:09

回答ありがとうございます。 ご指示頂いた通り修正したところ、無事に画面Aに文字列を表示させることができました。 しかし、画面Bで文字列を変更し、保存ボタンをタップして戻ったところ画面Aの文字列は変更前の文字列でした。アプリを一度落として再度立ち上げると最新の文字列になっているのですが…画面Bで保存ボタンを押した直後に画面Aの文字列も変更させることは可能なのでしょうか?追加で質問してすみません。よろしくお願いいたします;
hameji001

2019/01/01 17:11

viewDidAppearに書き込みましたでしょうか? viewDidLoad <- Viewが生成される時1回のみ走る viewDidAppear <- 表示される毎に毎回読み込まれるです。
rikkachan

2019/01/01 17:25 編集

すみません、追記してくださった文章を読んでおりませんでした。 追記ありがとうございました。 override func viewDidAppear() { self.title = UserDefaults.standard.string(forKey: "******") } を追記したところ、下記エラーが出たのですが、これは追記するのではなく、`DidLoad`を`Appear`に書き換えるのでしょうか? エラー内容 Method does not override any method from its superclass 度々すみません、よろしくお願いします。
hameji001

2019/01/01 17:27 編集

すみません、手書きしたのでコードが不足しておりました。 viewDidLoadはそのままにしておいてください。 下記のコードを他のfuncの括弧の中に入らないように 違うとこに追加してください。 override func viewDidAppear(_ animated: Bool) { self.title = UserDefaults.standard.string(forKey: "******") }
rikkachan

2019/01/01 17:29

ありがとうございます!解決しました! 追加でたくさん質問してしまいすみませんでした。 助かりました!
hameji001

2019/01/01 17:41 編集

さらに追記しておきますが、 保存するコードですが、 すっきりと UserDefaults.standard.set(listNameTextFiled.text!,forKey:"listName") の1行で大丈夫だと思います。 ちなみに最後の行の view.endEditing(true) の意味がピンと来ないですが、きっと必要なんですよね?
rikkachan

2019/01/01 18:18 編集

ありがとうございます! スッキリしました! view.endEditing(true)は参考にさせて頂いた記事の中に書いてあったコードで、コードの内容を調べ、キーボード外をタップした時にキーボードが閉じるようにするコード?のようなのですが、実機で試して見た所キーボードが閉じないのでちょっと保留にしていました。 あと、すみませんもう一つ追加で質問よろしいでしょうか。 アプリをDLして一番最初に画面Aに初期値をセットしたい場合、どのようなコードを追記したら良いのでしょうか。 ViewDidLoad()内にself.title = "初期値"を追記したのですが、うまくいきませんでした。 画面BのTextFieldの初期値はこのようになっています。 //TextFieldの初期値を設定する let defaults = UserDefaults.standard defaults.register(defaults: ["listName":"初期値"]) この初期値と同じ文字列を画面Aに持ってきたいです。 また、先ほど教えていただいた 「let defaults = UserDefaults.standardは不要」 とのことだったんですが、今コード全体を確認したら同じコードがTextFieldの初期値を設定するコードの中にも存在していて、ここの`let defaults = UserDefaults.standard`部分を削除したらエラーが出てしまったんですが、ここはこのまま残しておいても問題ないのでしょうか? 重ね重ねすみません。お手すきの時で結構ですので回答いただけると助かります。 よろしくお願いいたします。
hameji001

2019/01/01 18:36 編集

本来なら、別質問ということになると思いますが、 ついでなので答えさせていただきます。 viewDidLoadに記載されている self.title = "初期値"はきちんと働いておりますが、 viewDidAppearがその後に走るので、 その値で上書きされてしまうのです。 print文を両方のfunction内に記載すると、 その順番にコードが走っているのが確認できると思います。 また、アプリがない状態でインストールしたあとは UserDefaults.standard.string("listName")は空なので、 最初に表示されるタイトルは空になってるはずです。 なので、きちんと設定するなら、 viewDidLoadの self.title = "初期値" を if UserDefaults.standard.string(forKey:"listName).count == 0 { UserDefaults.standard.set("初期値", forKey:"listName") } に置き換えれば良いと思います。if文になっている理由は ない場合のみ設定するとし、起動2回目以降は働かないようにしています。
rikkachan

2019/01/02 15:23

回答ありがとうございました。 if UserDefaults.standard.string(forKey:"listName").count == 0 { UserDefaults.standard.set("初期値", forKey:"listName") } をViewDidLoad内に入れたら Value of optional type 'String?' must be unwrapped to refer to member 'count' of wrapped base type 'String' とエラーが出たので、「UserDefaults.standard.string("listName")は空なので」と言うのを思い出し、オプショナル型にして、nilを許可しようと思い、(forKey:"listName")の後ろに「!」を追記してBuildしたらアプリが落ちてしまい、「?」に書き換えたところ、アプリは落ちなくなったのですが、NavigationBar上に初期値はセットされていませんでした。 print文をviewDidAppearとviewDidLoadの両方に挟んでみたら、viewDidAppearの中に入れてるprint文のみが表示されてしまいました。 これはviewDidAppearにあるがまた上書きしてしまっているのでしょうか?
hameji001

2019/01/02 17:08

自分の環境だと、エラーの示唆の一番下のやつで、 if UserDefaults.standard.string(forKey:"listName")「!」.count == 0 { UserDefaults.standard.set("初期値", forKey:"listName") } と一箇所に!を入れるだけで、エラーは消えましたよ。 (forKey:"listName")の後ろに「!」をつけるだけです。 viewDidLoad内のとこで、試してみてください。
rikkachan

2019/01/04 17:13

override func viewDidAppear(_ animated: Bool) { // UserDefaultからリスト名を引っ張ってくる self.title = UserDefaults.standard.string(forKey: "listName") print("appear") } override func viewDidLoad() { super.viewDidLoad() // アプリ初起動時にリスト名に初期値を入れる if UserDefaults.standard.string(forKey:"listName")!.count == 0 { UserDefaults.standard.set("初期値", forKey:"listName") print("didLoad") } これで実機で試したんですが、Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional valueと言うエラーが出てしまいました。 もう少し原因を探して、わからなかったらまた新しく質問たてさせて頂きます。 ご丁寧に回答してくださって、ありがとうございました!
hameji001

2019/01/05 02:52 編集

画面Aの以下のfuncを override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. if UserDefaults.standard.string(forKey: "listName") == nil { UserDefaults.standard.set("初期設定", forKey: "listName") } else { print("初回じゃないよ") } } override func viewWillAppear(_ animated: Bool) { self.title = UserDefaults.standard.string(forKey: "titleString") } 以上のように置き換えてもらえれば大丈夫ですよ。 最初、userdefaultsを設定していない場合は、 結果はnilを返してきます。 なので、nilかどうかでif文の判定する必要がありました。
rikkachan

2019/01/06 14:52

ありがとうございます。 上記コードに書き換えたところ、無事初期値をセットすることができました。 長期間に渡り、質問に答えてくださって本当にありがとうございました。 助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問