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

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

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

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

Swift

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

Q&A

解決済

1回答

3831閲覧

【swift,xcode】labelに文字列を代入したらhread 1: Fatal error: Unexpectedly found nil while unwrapping an 0が発生

nekokichi

総合スコア54

Xcode

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

Swift

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

0グッド

0クリップ

投稿2018/09/22 09:35

イメージ説明

上記のセルをタップしたら、セルに表示されている、
・画像
・テキスト
を、

下記の画面に表示されている、
・ラベル(songと表示されているのと、Labelと表示されている)
・ImageView(ラベルの下にあります)
に渡す処理を実現したいです。

イメージ説明

そこで、セルを表示するViewControllerに、

ViewController

1 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 2 performSegue(withIdentifier: "goplay", sender: nil) 3 } 4 5 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 6 if segue.identifier == "goplay" { 7 let playvc = segue.destination as! PlayViewController 8// print(musiclibrary[path.row]["songname"]!) 9 playvc.songnameLabel.text = "a" 10 11// playvc.artistNameLabel.text! = musiclibrary[path.row]["artistname"]! 12// playvc.imageView.image! = UIImage(named: musiclibrary[path.row]["image"]!)! 13 } 14 }

を追記し、PlayViewControllerにある、

PlayViewController

1 @IBOutlet weak var songnameLabel: UILabel! 2 3 @IBOutlet weak var artistLabel: UILabel! 4 5 override func viewDidLoad() { 6 super.viewDidLoad() 7 8 songnameLabel.text = "song" 9 10 // Do any additional setup after loading the view. 11 } 12 13 @IBOutlet weak var imageView: UIImageView! 14

の各UIパーツに値を渡す処理を書きました。

しかしシミュレータで実行したら、

ViewController

1playvc.songnameLabel.text = "a" 2

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

というエラーが発生しました。

あらかじめPlayViewControllerのsongnameLabelに"song"という文字列で初期化しましたが、ダメでした。

text!と追記しても、やはりダメでした。

画面は遷移するのですが、PlayViewControllerに値を渡す処理を書くと、エラーが出ます。

どうかご回答よろしくお願いします!!

ViewController

1import UIKit 2 3class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource{ 4 5 //曲名、アーティスト名、index、画像 6 var musiclibrary = 7 [["songname":"ヒーリング1","artistname":"魔王魂","index":"0","image":"healing1.jpg"], 8 ["songname":"ヒーリング2","artistname":"魔王魂","index":"1","image":"healing2.jpg"], 9 ["songname":"ヒーリング3","artistname":"魔王魂","index":"2","image": "healing3.jpg"], 10 ["songname":"バトル1","artistname":"魔王魂","index":"3","image":"battle.jpg"], 11 ["songname":"サイバー","artistname":"魔王魂","index":"4","image": "cyber.jpg"]] 12 13 var path = IndexPath() 14 15 @IBOutlet weak var tableView: UITableView! 16 17 override func viewDidLoad() { 18 super.viewDidLoad() 19 20 tableView.delegate = self 21 tableView.dataSource = self 22 23 self.tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier:"cell") 24 25 } 26 27 func numberOfSections(in tableView: UITableView) -> Int { 28 return 1 29 } 30 31 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 32 return 5 33 } 34 35 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 36 let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell 37 38 cell.setting(indexPath: indexPath) 39 40 return cell 41 } 42 43 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 44 45 return 120 //セルの高さ 46 } 47 48 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 49 performSegue(withIdentifier: "goplay", sender: nil) 50 } 51 52 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 53 if segue.identifier == "goplay" { 54 let playvc = segue.destination as! PlayViewController 55// print(musiclibrary[path.row]["songname"]!) 56 playvc.songnameLabel.text = "a" 57// playvc.songnameLabel.text? = "a" 58 59// playvc.artistNameLabel.text! = musiclibrary[path.row]["artistname"]! 60// playvc.imageView.image! = UIImage(named: musiclibrary[path.row]["image"]!)! 61 } 62 } 63 64} 65

PlayViewController

1import UIKit 2import AVFoundation 3 4class PlayViewController: UIViewController { 5 6 //曲名を格納した配列 7 let song = ["ヒーリング1","ヒーリング2","ヒーリング3","バトル1","サイバー1"] 8 9 var playid = 0 10 11 @IBOutlet weak var songnameLabel: UILabel! 12 13 @IBOutlet weak var artistLabel: UILabel! 14 15 override func viewDidLoad() { 16 super.viewDidLoad() 17 18 songnameLabel.text = "song" 19 20 // Do any additional setup after loading the view. 21 } 22 23 @IBOutlet weak var imageView: UIImageView! 24 25 @IBAction func playAction(_ sender: Any) { 26 } 27 28 @IBAction func backAction(_ sender: Any) { 29 } 30 31 @IBAction func nextAction(_ sender: Any) { 32 } 33 34 @IBAction func repeatAction(_ sender: Any) { 35 } 36 37 @IBAction func shuffleAction(_ sender: Any) { 38 } 39 40 41} 42

イメージ説明

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

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

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

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

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

guest

回答1

0

ベストアンサー

songnameLabelがnilな為です。
storyboardでPlayerViewControllerと接続されてあるか確認してください。

追記:
すみません。
prepare(for:sender:)が呼ばれた時点ではまだOutletが接続されていないせいですね。
あまりsegueは使わないので知りませんでした。

ではどうすればいいかですが、方法は2つあります。
どちらを使ってもいいですが、以下の理由で方法1をお勧めします。

  • ViewControllerがPlayViewControllerの内部構造(保持するビュー)に依存する
  • _ = playvc.viewというコードに意味が見えない為うっかり削除されかねない

方法1

prepare(for:segue)では次画面に値を渡すだけにします。

Swift

1class ViewController { 2 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 3 if segue.identifier == "goplay" { 4 let playvc = segue.destination as! PlayViewController 5 playvc.music = musiclibrary[path.row] 6 } 7 } 8}

次画面のviewDidLoad()で受け渡された値をビューにセットします。

Swift

1class PlayViewController { 2 var music: [String: String]? 3 4 override func viewDidLoad() { 5 super.viewDidLoad() 6 if let music = music { 7 print(music["songname"]!) 8 // 受け渡されたmusicをビューにセットする 9 self.songnameLabel.text = "a" 10 11// self.artistNameLabel.text = music["artistname"] 12// self.imageView.image = UIImage(named: music["image"]!) 13 } 14 } 15}

方法2

Outletはviewが初めてアクセスされた時に自動で接続されます。
つまりviewにアクセスすればOutletを繋ぐことができます。

Swift

1class ViewController { 2 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 3 if segue.identifier == "goplay" { 4 let playvc = segue.destination as! PlayViewController 5 // これでビューが読み込まれるのでOutletにアクセスできる 6 _ = playvc.view 7 8// print(musiclibrary[path.row]["songname"]!) 9 playvc.songnameLabel.text = "a" 10// playvc.songnameLabel.text? = "a" 11 12// playvc.artistNameLabel.text! = musiclibrary[path.row]["artistname"]! 13// playvc.imageView.image! = UIImage(named: musiclibrary[path.row]["image"]!)! 14 } 15 } 16}

投稿2018/09/22 12:10

編集2018/09/22 13:43
u39ueda

総合スコア950

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

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

nekokichi

2018/09/22 12:48

再接続しましたが、ダメですね。 perFormSegueのsenderをselfにしても効果ありません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問