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

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

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

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

Swift

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

Q&A

解決済

1回答

3706閲覧

【Swift】画面遷移時の値引き継ぎ

Ruthi

総合スコア65

Xcode

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

Swift

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

0グッド

1クリップ

投稿2017/04/13 06:18

編集2017/04/14 01:50

###前提・実現したいこと
Xcode8.0/Swift3で簡易的なBMI値の計算アプリを作っています
入力画面で身長、体重、年齢の値を入力、計算ボタンを押すと計算し、BMI値や肥満度など複数の結果を結果画面の変数に代入
結果画面へ引き継ぎを行い、遷移して結果表示という処理を行いたいのですが、変数の引き継ぎに関する部分がなかなか上手くできません

ボタンを押した時に値が正しく入力されていなかったり、入力された値が極端に小さい、大きい場合は画面は遷移せずエラーメッセージを出すようにしたいので
ボタンを押した時の@IBAction内に記述することで画面遷移と変数の引き継ぎ処理を行っています

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

計算ボタンを押した時、画面は遷移するが結果画面の答えを表示するラベルには反映されない

###該当のソースコード

Swift

1 FirstViewController.Swift 2 3 @IBAction func Calculation(_ sender: Any) { 4 //テキストフィールドに入力された身長と体重の値をfloat型に変換 5 let height:Float? = Float(Textheight.text!) 6 let weight:Float? = Float(Textweight.text!) 7 let age:Int? = Int(Textage.text!) 8 9 //追記箇所 10 //身長もしくは体重に何も入力されていない場合(エラー) 11 if height == nil || weight == nil 12 { 13 Error.text = "正常に値が入力されていないため\n計算できません。\n再入力してください。" 14 } 15 16 //身長が80cm以下or220cm以上、体重が20kg以下or300kg以上(異常数値を弾く処理) 17 else if height! <= 80 || height! >= 220 || weight! <= 20 || weight! >= 300{ 18 Error.text = "規定の範囲外のため\n計算できません。\n再入力してください。" 19 } 20 21 //後々結果画面のテキストへ代入するBMI値や肥満度を代入する変数の宣言 22 var Ca:String! 23 var St:String! 24 var Ad:String! 25 var StWe:String! 26 var Id:String! 27 var Me:String! 28 29 // 30 //入力された身長、体重などからBMI値の計算処理を行うプログラム 31 //(今回の内容には特に関係ないため省きます) 32 //この処理の中で上記で宣言してあるCaやStに算出されたBMI値等を代入しています 33 // 34 35 present(SecondViewController, animated: true, completion: nil) 36 37 } 38 //SecondViewControllerの 39 override func prepare(for segue: UIStoryboardSegue, sender: Any?){ 40 let Second = segue.destination as! SecondViewController 41 //BMI値等算出された値を渡す 42 Second.Cal = Ca 43 Second.Sta = St 44 Second.Adv = Ad 45 Second.StaWei = StWe 46 Second.Ide = Id 47 Second.Met = Me 48 } 49

Swift

1 SecondViewController.Swift 2 3 import UIKit 4 5class SecondViewController: UIViewController { 6 7 //UIラベルの設定 8 //をここで行っています 9 10 //ViewControllerから受け取る変数 11 var Cal = "" 12 var Sta = "" 13 var Adv = "" 14 var StaWei = "" 15 var Ide = "" 16 var Met = "" 17 18 override func viewDidLoad() { 19 super.viewDidLoad() 20 21 //ラベルにFirstViewControllerから受け取った値を表示 22 CalculationResult.text = Cal 23 Standard.text = Sta 24 Advice.text = Adv 25 StandardWeight.text = StaWei 26 Ideal.text = Ide 27 MetabolismStandard.text = Met 28 29 // Do any additional setup after loading the view. 30 } 31 32 override func didReceiveMemoryWarning() { 33 super.didReceiveMemoryWarning() 34 // Dispose of any resources that can be recreated. 35 } 36

###補足情報(言語/FW/ツール等のバージョンなど)
冒頭でも述べた通り
Xcode8.0
Swift3
で作っています

Swiftを触り始めてまだほんの少ししか経っておらず粗だらけのプログラムですがどうかご教授のほどよろしくお願い致します

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

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

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

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

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

guest

回答1

0

ベストアンサー

prepare(for:​sender:​)をCalculation(_:)の外に出して、

swift

1//画面の遷移 2let storyboard: UIStoryboard = self.storyboard! 3let nextView = storyboard.instantiateViewController(withIdentifier: "SecondView") 4present(nextView, animated: true, completion: nil)

swift

1//画面の遷移 2present(SecondViewController, animated: true, completion: nil) 3//※遷移するViewControllerは新たに生成するのではなくセグエで渡されたものを使う

に変更して下さい。

※SecondViewControllerという変数名はクラス名と同じで紛らわしいので変えた方がいいです。

投稿2017/04/13 06:47

fuzzball

総合スコア16731

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

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

Ruthi

2017/04/13 07:01

回答ありがとうございます。 Calculation(_:)の外に出すとなるとボタンが押下された際の処理から外れ、値の引き継ぎが行われないまま遷移してしまうのではないかと思うのですが違うのでしょうか? 変数名は変更致します、ありがとうございます。
fuzzball

2017/04/13 07:17

prepare(for:​sender:​)は、遷移する直前に呼ばれます。 そもそも今は、prepare(for:​sender:​)は実行されていないと思いますが。(中にprint文を入れて確かめてみて下さい)
Ruthi

2017/04/13 07:36

prepare(for:​sender:​)の仕様については知りませんでした…ありがとうございます。 確かに実行されていませんでした、画面の遷移だけは動いていたので混同していたみたいです。 //遷移するViewControllerは新たに生成するのではなくセグエで渡されたものを使う ここの部分が分からないのですが、StoryBoard上でFirstViewControllerからSecondViewControllerへセグエを伸ばすのとは違う手法があるということですか?
fuzzball

2017/04/13 07:42 編集

「StoryBoard上でFirstViewControllerからSecondViewControllerに伸ばしたセグエ」がprepare(for:​sender:​)に渡されます。そこから取り出したもの(segue.destination)が、これから遷移するViewControllerです。 あなたも、値を引き継ぐためにそのViewControllerに値をセットしているじゃないですか。
fromageblanc

2017/04/13 08:34

セグエ作ってるなら、performSegueメソッドでもいいんじゃないですか。画面遷移。
Ruthi

2017/04/13 08:36

調べ直して少々理解が追いついて来ましたが、「Cannot convert value of type 'SecondViewController.Type' to expected argument type 'UIViewController'」というエラーが出ます。 わざわざお教えいただいたのに申し訳ありません、もう少し格闘してきます。
Ruthi

2017/04/13 08:38

>fromageblanc氏 ありがとうございます、調べて来ます。
fuzzball

2017/04/13 08:51

@Ruthiさん 質問内のコードを現状のものに更新し、どこでエラーが出ているのか書いて下さい。
Ruthi

2017/04/14 00:18

お返事遅れ申し訳ありません。 コードを更新いたしました。 お教えいただいた present(SecondViewController, animated: true, completion: nil)のSecondViewConrtollerからエラーが出ています。 SecondViewConrtollerの部分をStoryboard ID等いろいろ思い当たるものに書き換えを行ってもほぼほぼ同一の結果となりました。 エラー内容を調べたのですがTypeA(この場合はSecondViewController)をTypeB(この場合はUIViewController)に変換できない?という旨の解説が出てきました
fuzzball

2017/04/14 00:40 編集

最初の方に書いた変数SecondViewControllerの名前を変更して下さい。
Ruthi

2017/04/14 00:56

申し訳ありません、記入漏れです。 変数SecondViewControllerは現在Secondという名前になっております。コードもそのように修正し直しました。
fuzzball

2017/04/14 01:06

いつの間にかpresent(...)がCalculation(_:)の中に移動していますが、これは不要なので削除して下さい。 (ちなみにpresent(...)内のSecondViewControllerは変数名なので、現在ならSecondになります。紛らわしいでしょ?) 一旦これでどうなるか試して下さい。
Ruthi

2017/04/14 01:31

質問当初の目的が「ボタンが押された時に計算、変数引き継ぎ、画面遷移を行いたい」なので最初からCalculation(_:)の中にpresent(...)はいたはずなのですが、必要ないのですか? (念のため削除する前にpresent(...)内のSecondViewControllerをSecondに変えてみましたが、prepare(for:sender:)がCalculation(_:)の外にいるからか定義されていないというエラーが出ました) presentを削除するとエラーは消えましたが正常な値を入力した上で計算ボタンを押しても画面は遷移しなかったです ViewControllerからセグエを伸ばしているので当然かもしれませんが……
fuzzball

2017/04/14 01:35

今あるセグエはFirstViewControllerとSecondViewControllerを繋いでいるManualなセグエだと思うので、これを削除し、ボタンとSecondViewControllerをセグエで繋いで下さい。
Ruthi

2017/04/14 01:55

ボタンと繋いだら正常に画面が遷移し、遷移先の画面で正しい計算結果が表示されるのを確認できました、ありがとうございます! しかし現状だと入力画面で身長、体重、年齢の値に何も入力されていない等のエラーメッセージが表示されるはずの状態(一応質問のコードにエラーメッセージ表示部分を追記しました)であっても、計算ボタンを押すと問答無用で画面が遷移してしまいます (これを経験したのでFirstViewControllerからセグエを伸ばす方法に切り替えたのですが逆にダメだったのですね) これに関してプログラムで制御する方法はあるのでしょうか? 以前インターネットで調べた時は「アプリ側で遷移を制御したい場合はViewControllerから伸ばすと良い」というような記述を見たので……
Ruthi

2017/04/14 01:55

制御する方法があるかないか、という点だけでも教えていただけると助かります。
fuzzball

2017/04/14 02:04

>>エラー処理 あー、そうですね。すみません。ボケてました。 セグエは元のManualセグエに戻して下さい。 で、fromageblancさんがコメントされているように、performSegue(withIdentifier:sender:)でセグエを発動して下さい。(エラーが無かったときだけ)
Ruthi

2017/04/14 02:18

performSegue(withIdentifier:sender:)で実行したらエラーのある時は遷移せずメッセージ表示、エラーのない時は遷移して結果表示という望んだ通りの動きができました! prepare(for:​sender:​)が遷移直前に呼ばれるという点等これまで知らなかったことまで教えていただいて非常に助かりました。 何度も質問で返したり無知を晒したりとお見苦しいところをお見せして申し訳ありませんでした。 fuzzballさん、fromageblancさんこの度は本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問