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

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

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

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

Q&A

1回答

1480閲覧

TextFieldの値を受け渡す際のエラーについて

Ryohya

総合スコア0

Swift

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

0グッド

0クリップ

投稿2020/09/15 10:17

前提・実現したいこと

プログラミング初心者です。 結論から申し上げますと、TextFieldに入力された値を画面遷移で次のViewControllerに受け渡し計算に使用したいです。

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

6つテキストフィールドがあるうちの数字を入れる3つが空欄の場合にエラーが起きてしまいます。

Unexpectedly found nil while unwrapping an Optional value

該当のソースコード

Swift

1import UIKit 2 3class ViewController: UIViewController 4 5 @IBOutlet var MetalNameField1 : UITextField! 6 @IBOutlet var MetalNameField2 : UITextField! 7 @IBOutlet var MetalNameField3 : UITextField! 8 @IBOutlet var MetalRatioField1 : UITextField! 9 @IBOutlet var MetalRatioField2 : UITextField! 10 @IBOutlet var MetalRatioField3 : UITextField! 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 // Do any additional setup after loading the view. 15 } 16 17 18@IBAction func gotoSecond() { 19 if(MetalNameField1.text != "" && MetalNameField2.text != "" && MetalNameField3.text != "" && MetalRatioField1.text != "" && MetalRatioField2.text != "" && MetalRatioField3.text != "" ) { 20 21 if element.contains(MetalNameField1.text!) && element.contains(MetalNameField2.text!) && element.contains(MetalNameField3.text!) { 22 23 self.performSegue(withIdentifier: "toSecond", sender: nil) //画面遷移をするコード 24 }else{ 25 noneAlert() 26 } 27 28 }else{ 29 //フィールドが空のときに呼び出される 30 karaAlert() 31 } 32 } 33 34. 35. 36. 37 38override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 39 40 if segue.identifier == "toSecond" { 41 let nextVC = segue.destination as! SecondViewController 42 nextVC.MetalName1 = MetalNameField1.text! 43 nextVC.MetalName2 = MetalNameField2.text! 44 nextVC.MetalName3 = MetalNameField3.text! 45 nextVC.MetalRatio1 = Double(MetalRatioField1.text!)! 46 nextVC.MetalRatio2 = Double(MetalRatioField2.text!)! 47 nextVC.MetalRatio3 = Double(MetalRatioField3.text!)! 48 49 } 50} 51

イメージ説明

試したこと

関連付けなどを確認しましたが、関連付けに間違っている点はなかったです。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

発生しているエラーは、「nil を強制的にアンラップしているために発生する」エラーです。

エラーとして考えられる要因は3つあります。

まず一つ目は、@IBOutlet による関連付けです。

関連付けうまくいっていなければ、

Swift

1@IBOutlet var MetalRatioField1 : UITextField!

この MetalRatioField1nil ということはないかと思います。

二つ目は、MetalTextField1 のプロパティである text です。

この変数はオプショナル型で宣言してあるため、nil が入っている可能性が否定できません。ただし、通常初期値は "" (からの文字列)であるため、可能性は低いと思います。

三つ目は、Double()のイニシャライザです。

Swift

1nextVC.MetalRatio1 = Double(MetalRatioField1.text!)!

という具合に、Double のイニシャライザに!をつけてアンラップを行なっていますが、ここが原因の可能性が高いと見ています。

公式ドキュメントを見ていただければわかりますが、

text
The input string to convert to a Double instance. If text has invalid characters or is in an invalid format, the result is nil.

という記述があります。入力に与えている値(つまりtext)が不正な値や書式の場合、Doublenil を返す仕様となっています。

おそらく、該当するフィールドに入力した文字列が、Double として変換できない文字列なのではないでしょうか。

たとえば、

Swift

1print(MetalRatioField1.text) 2nextVC.MetalRatio1 = Double(MetalRatioField1.text!)!

という具合記述して、デバッグエリアに変換させたい値を表示させると、クラッシュ時にどのような文字列が渡ってきたか確認することが可能です。

ここで得られた値と、公式ドキュメント中にある変換例を見比べてみて、クラッシュした原因を解明されてはいかがでしょうか。

##20200916追記

テキストフィールとを強制アンラップするには、textField.text! のように変数名の最後に ! をつければ強制アンラップになります(コメントではつけていたのですが、見にくかったかもしれません)。

あるいは、たとえば下記の例ように、Stringの Extension を作り、ある文字列が Double 型に変換できるか判別させる方法もあるかと思います。

Swift

1 @IBAction func confirmButton(_ sender: Any) { 2 if textField.text!.isEmpty { 3 print("文字列入力なし") 4 } else { 5 print("入力文字列は: ", textField.text!) 6 } 7 8 if !doubleField.text!.isDouble() { 9 print("Doubleではない") 10 } else { 11 print("入力された数値は: ", Double(doubleField.text!)!) 12 } 13 } 14} 15 16extension String { 17 func isDouble() -> Bool { 18 if let _ = Double(self) { 19 return true 20 } else { 21 return false 22 } 23 } 24}

投稿2020/09/15 11:39

編集2020/09/15 20:32
TsukubaDepot

総合スコア5086

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

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

Ryohya

2020/09/15 12:06

ご回答ありがとうございます。printを用いて確認したところ、optional("")が渡っていることがわかりました。この場合、if文を1つ追加して、数字が入力されていない場合は、アラートを表示する文を記すことで解決できるのでしょうか...?
TsukubaDepot

2020/09/15 12:28

念のためいま確認したのですが、Double("") とイニシャライザに渡す文字列が「から」の場合、戻り値は nil となるようす。 なので、 MetalRatioField1.text != "" を Double(MetalRatioField1.text) != nil として、そもそも Double に変換できるかチェックする方法も一つかと思います(もっと効率の良い方法もあると思いますが、とりあえず)。
Ryohya

2020/09/15 13:24

親身にありがとうございます。 Double(MetalRatioField2.text) != nilで試みると、Initializer 'init(_:)' requires that 'String?' conform to 'StringProtocol'というエラーになってしまいました...。難しいですね...。
TsukubaDepot

2020/09/15 13:25

すみません、 Double(MetalRatioField1.text!) != nil と、テキストフィールドのアンラップが必要です。
Ryohya

2020/09/15 13:54

ありがとうございます。本当に初歩的で申し訳ないのですが、テキストフィールド のアンラップの書き方を教えていただけますでしょうか...。勉強不足で申し訳ないです。
TsukubaDepot

2020/09/15 20:32

回答本文に追記しましたので、そちらをご確認いただけますでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問