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

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

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

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

Q&A

解決済

2回答

1481閲覧

swiftで1問の正誤判定画像を消すコードを入れたら2問目がエラーになる対策

Tomzy

総合スコア104

Swift

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

0グッド

0クリップ

投稿2017/08/09 07:30

「世界一受けたい iPhoneアプリ開発の授業 Chapter7-2
四択検定アプリを作ろう」を参考にして問題に○ x イメージを付けるのは成功し次問にも移れたのですが、次問に移る時の正誤判定イメージが消えないので下記のコードを付け加えました。

judgeImageView.removeFromSuperview()

イメージは消えたのですが、次問に移るとエラーがでてアプリが落ち、fatal error: unexpectedly found nil while unwrapping an Optional valueと表示されます。この部分をCommentOutすると次問に移ることができ次問の正誤判定はします。但し前問の判定が残ります。

全コードを下記のとおり掲載しますので、その原因を教えてください。
問題箇所として//◎を2カ所付しました。

// MondaiViewController.swift
// Mondai01
//
// Created by

import UIKit
class MondaiViewController: UIViewController, UITextFieldDelegate {

//音声問題.csvファイルを格納する配列csvArray @IBOutlet weak var mondaiNumberLabel: UILabel! @IBOutlet weak var mondaiField: UITextField! @IBOutlet weak var kaitouField: UITextField! @IBOutlet weak var judgeImageView: UIImageView! @IBOutlet weak var answerBtn: UIButton! //"OnseiTextsCSV"ファイルを格納する配列csvArray var csvArray:[String] = [] //csvArrayから取り出した問題を格納する配列mondaiArray var mondaiArray:[String] = [] var mondaiCount = 0 //問題をカウントする変数 var correctCount = 0 //正解をカウントする変数 let total = 10 //出題数を管理する変数 var nextBtn = UIButton() override func viewDidLoad() { super.viewDidLoad() print ("ここまで来たaaa") let viewController = ViewController() //loadCSVメソッドを使用し、csvArrayに検定問題を格納 csvArray = viewController.loadCSV("OnseiTextsCSV") //csvArrayの0行目を取り出し、カンマを区切りとしてmondaiArrayに格納 mondaiArray = csvArray[mondaiCount].components(separatedBy: ",") //変数mondaiCountに1を足して、ラベルに出題数を設定 mondaiNumberLabel.text = "第\(mondaiCount+1)問" //TextViewに問題を設定 mondaiField.text = mondaiArray[0] //テキストビューに自動でキーボード表示 kaitouField.becomeFirstResponder() // Delegate を設定 kaitouField.delegate = self // プレースホルダー kaitouField.placeholder = "マイクで問題を読む" }

//回答ボタンをタップした時の回答正誤の判定と○X表示

@IBAction func btnAction(_ sender: UIButton) { print ("ここまで来たaaa222") if mondaiField.text == kaitouField.text { //○を表示 judgeImageView.image = UIImage(named: "maru.png") print ("ここまで来たbbb") //正解カウントを増やす correctCount += 1 }else{ //間違っていたら×を表示

//◎最初は表示されますが、次問になるとエラーになります。

print ("ここまで来たccc") judgeImageView.image = UIImage(named: "batsu.png") print ("ここまで来たccc2222") } //回答ボタンの使用停止 answerBtn.isEnabled = false } func btn02Action(_ sender: UIButton) { func nextQuestion(){ //問題カウント変数をカウントアップ mondaiCount += 1 //mondaiArrayに格納されている問題配列を削除 mondaiArray.removeAll() //csvArrayから次の問題配列をmondaiArrayに格納 mondaiArray = csvArray[mondaiCount].components(separatedBy: ",") //◎ここが追加したコード⇒ここをCommentOutすると次問の正誤判定はできます。 //次問のボタンを押しても前の正誤判定が消えないので回答イメージの表示を止める judgeImageView.removeFromSuperview() //問題数ラベル、問題表示TextView、選択肢ボタンに文字をセット mondaiNumberLabel.text = "第\(mondaiCount+1)問" mondaiField.text = mondaiArray[0] //回答ボタンの使用開始 answerBtn.isEnabled = true func btnAction(_ sender: UIButton) { print ("ここまで来たaaa333")

//
}
print ("ここまで来たddd")
//print ("ここまで来たddd-2")
// //if-else文を追加。mondaiCountがtotalに達したら画面遷移
if mondaiCount < total {

//csvArrayから次の問題配列をmondaiArrayに格納 mondaiArray = csvArray[mondaiCount].components(separatedBy: ",") //問題数ラベル、問題表示TextView、選択肢ボタンに文字をセット mondaiNumberLabel.text = "第\(mondaiCount+1)問" mondaiField.text = mondaiArray[0] } else{ //Stroyboard SegueのIdentifierを引数に設定して画面遷移 performSegue(withIdentifier: "score", sender: nil) print ("ここまで来たeee") } } judgeImageView.isHidden = false //nextQuestionメソッドを呼び出す nextQuestion() print ("ここまで来たfff") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. }

}

ご参考までに画像を添付します。 1問の正誤判定です ![イメージ説明](99dfeafac665361fc1df12f1d5138ceb.png) 2問に移りました1問の正誤判定は消えています ![イメージ説明](779b7bb2ede5079317fd37ca12acb0f5.png) 2問に回答を入れました。 ![イメージ説明](479d1776dff8d3738f9143c4c386fe03.png) ここで回答ボタンを押すとエラーになります。 画像の「もどる」は次問に移るボタンを意味します。 ストーリーボードとコードは結ばれています。 開発環境は下記のとおりです。 MacBookPro OS-X10.12.6 Sierra Xcode 8.3.3 (8E3004b) よろしくお願いします。

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

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

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

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

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

guest

回答2

0

自己解決

judgeImageView.isHidden = true
にしましたら、エラーにはならず、正誤判定イメージは消えますが、その後の挙動がおかしくなりました。つまりその後の正誤判定をしないし、回答ボタンが無効になったりします。

一方、judgeImageView.removeFromSuperview()
をやめて
judgeImageView.image = nil にしたら、エラーにはならず、正誤判定イメージは消えますし、次問の答えに応じて正誤判定を行います。思ったとおりに動きました。

投稿2017/08/10 01:44

Tomzy

総合スコア104

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

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

0

表示/非表示の切り替えは.isHiddenプロパティで行って下さい。

【補足】

なぜ落ちるのか書いておきます。
StoryboardとのOutletはweakで繋がっていますので、removeFromSuperview()するとViewから取り除かれるだけではなく、judgeImageViewそのものが解放されていまいます。(judgeImageView == nil になっているということ)
その状態でimageプロパティにアクセスしようとして落ちているのだと思います。

投稿2017/08/09 07:38

編集2017/08/10 00:16
fuzzball

総合スコア16731

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

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

Tomzy

2017/08/09 11:59

ありがとうございました。 judgeImageView.removeFromSuperview() をやめて judgeImageView.image = nil に換えましたら、思ったとおりに動きました。
Tomzy

2017/08/09 12:20

上記を補足します。 judgeImageView.isHidden = true にしましたら、エラーにはならず、正誤判定イメージは消えますが、その後の挙動がおかしくなりました。つまりその後の正誤判定をしないし、回答ボタンが無効になったりします。 一方、judgeImageView.image = nil にしたら、エラーにはならず、正誤判定イメージは消えますし、次問の答えに応じて正誤判定を行います。
fuzzball

2017/08/10 00:19

違う方法で解決したのであれば、自分で回答を書き、ベストアンサー(この方法で解決した)にして下さい。 isHiddenで挙動がおかしくなる原因はちょっと分かりませんが、今回の処理の流れの場合、image = nil の方が良い解決方法だと思います。
Tomzy

2017/08/10 01:40

fuzzballさんへ 了解しました。お手数をかけてごめんなさい。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問