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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

Q&A

解決済

2回答

593閲覧

pageviewcontrollerを使った、UIImageの値の受け渡しができません。

shima_shima

総合スコア16

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

0グッド

1クリップ

投稿2019/02/21 02:48

前提・実現したいこと

ストーリーボード上で
uiviewcontrollerの一部にpageviewcontrollerをいれ、その中にuicollectionviewcontrollerを配置し、cellには画像をいれています。
イメージ説明

実現したいのは、uicollectionviewcontrollerで画像を選択すると、uiviewcontrollerのimageviewに選択された画像が表示されるようにしたいです。

現在は以下までできています。

イメージ説明

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

collectionviewのdidselectメソッドで画像の名前を取得し、値を渡したいのですが、uiimageviewがnilになってしまいます。

イメージ説明

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

該当のソースコード

PostViewController

import UIKit class PostViewController: UIViewController, UITextFieldDelegate, UIPageViewControllerDataSource { @IBOutlet weak var bgAnimationView: UIView! @IBOutlet weak var emotionImage: UIImageView! let sboard: UIStoryboard? = UIStoryboard(name:"Main", bundle:nil) var pageViewControllers: [UIViewController] = [] var defaultStampImageNames: [String] = [] var myStampImageNames: [String] = [] var selectedImage: UIImage? { didSet{ self.emotionImage!.image = self.selectedImage self.emotionImage.setNeedsLayout() } } func setup() { // stamp画像の取得 defaultStampImageNames = ["heart_icon", "heart_icon"] myStampImageNames = ["heart_icon", "heart_icon"] } override func viewDidLoad() { super.viewDidLoad() setup() //スタンプ選択フィールドのページング実装 let defaultStampViewController: DefaultStampViewController = sboard!.instantiateViewController(withIdentifier: "DefaultStampViewController") as! DefaultStampViewController //スタンプ画像をコレクションビューに設定 defaultStampViewController.stampImages = defaultStampImageNames let myStampViewController: MyStampViewController = sboard!.instantiateViewController(withIdentifier: "MyStampViewController") as! MyStampViewController //スタンプ画像をコレクションビューに設定 myStampViewController.stampImages = myStampImageNames //UIPageViewControllerの取得 let pageViewController:UIPageViewController? = children[0] as? UIPageViewController //dataSourceに自分自身を設定 pageViewController?.dataSource = self pageViewControllers = [defaultStampViewController,myStampViewController] //UIPageViewControllerに表示対象を設定 pageViewController?.setViewControllers([pageViewControllers[0]], direction: .forward, animated: false, completion: nil) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.view.backgroundColor = UIColor(hex: "FEC82A") startBackgroundAnimation() } //ページコントローラーの処理 func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController:UIViewController) -> UIViewController? { //右にスワイプした場合に表示したいviewControllerを返す //ようはページを戻す let index = pageViewControllers.index(of: viewController) if index == 0 { return nil } else { return pageViewControllers[index!-1] } } //ページコントローラーの処理 func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { //左にスワイプした場合に表示したいviewControllerを返す //ようはページを進める let index = pageViewControllers.index(of: viewController) if index == pageViewControllers.count-1 { return nil } else { return pageViewControllers[index!+1] } } //リターンを押されたとき func textFieldShouldReturn(_ textField: UITextField) -> Bool { return true } //背景アニメーション func startBackgroundAnimation() { let bgImage = UIImage.init(named: "background_icon")! bgAnimationView.backgroundColor = UIColor.init(patternImage: bgImage) bgAnimationView.frame.size = CGSize(width: view.frame.width + bgImage.size.width, height: view.frame.height + bgImage.size.height) let startOrigin = CGPoint(x: -bgImage.size.width, y: 0) let endOrigin = CGPoint(x: 0, y: -bgImage.size.height) bgAnimationView.frame.origin = startOrigin UIView.animate(withDuration: 1.3, delay: 0.0, options: [.repeat, .curveLinear], animations:{ self.bgAnimationView.frame.origin = endOrigin }, completion: nil) } //閉じる @IBAction func back(_ sender: Any) { dismiss(animated: true, completion: nil) } }

DefaultStampViewController

import UIKit private let reuseIdentifier = "defaultStamp" class DefaultStampViewController: UICollectionViewController { var stampImages: [String] = [] override func viewDidLoad() { super.viewDidLoad() // Uncomment the following line to preserve selection between presentations // self.clearsSelectionOnViewWillAppear = false // Register cell classes // Do any additional setup after loading the view. } // MARK: UICollectionViewDataSource override func numberOfSections(in collectionView: UICollectionView) -> Int { // #warning Incomplete implementation, return the number of sections return 1 } override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of items return stampImages.count } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell :DefaultStampViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! DefaultStampViewCell let cellImg = UIImage(named: stampImages[indexPath.item]) cell.stampImg.image = cellImg cell.backgroundColor = UIColor.clear return cell } override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let selectedImage = UIImage(named: stampImages[indexPath.item])! let postViewController: PostViewController = storyboard!.instantiateViewController(withIdentifier: "Post") as! PostViewController //postViewController.setImage(newImage: selectedImage) postViewController.selectedImage = selectedImage } }

試したこと

調べてみたところ

let _ = self.view

をしてviewの再描画?をするなどの対処法があったのですが、使い方がわからずいれてみてもこれも上手くいかず、、、
(他に入れ方があるのか?)

どなたか助けてください!????

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

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

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

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

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

guest

回答2

0

ベストアンサー

@IBOutlet weak var bgAnimationView: UIView!
@IBOutlet weak var emotionImage: UIImageView!

この2つがそもそもStoryboardと紐付いていないのではありませんか?

投稿2019/02/21 06:45

takabosoft

総合スコア8356

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

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

shima_shima

2019/02/21 11:52

確認したのですが、きちんと紐づけはされているようです、、、
takabosoft

2019/02/22 00:41 編集

了解です、問題となる部分を勘違いしておりました。 storyboard使わない派なのでちょっと認識が怪しいのですが、 storyboard!.instantiateViewController(withIdentifier: "Post")はすでに画面に表示されているインスタンスを取得するのではなく、新たにViewControllerを生成していませんかね? https://developer.apple.com/documentation/uikit/uistoryboard/1616214-instantiateviewcontroller "This method creates a new instance of the specified view controller each time you call it."という部分です。 shima_shimaさんがやりたいのは、「新しいPostViewControllerインスタンスを作ること」ではなくて、「すでに画面に表示されているPostViewControllerインスタンスを取得する」、ですよね? さて、それはどうやってやるんでしょうか(やり方はいろいろありそうですが、PostViewControllerのインスタンスを各ページにそのまま渡しちゃえばとりあえずは動きそうです)。
shima_shima

2019/02/25 04:13

takabosoftさん、ご回答ありがとうございます! defaultviewcontrollerで「var postViewController: PostViewController?」を宣言し、 postviewcontrollerのviewdidloadで、「defaultviewcontroller.postViewController = self」で受け渡し、 defaultviewcontroller内のdidselectedメソッドで「postViewController.selectedImage = selectedImage」で受け渡すことができました!! ありがとうございます!
takabosoft

2019/02/25 05:45

はーい。たぶん循環参照していると思うので、弱参照、つまり、 weak var postViewController: PostViewController? にしたほうがいいかもしれません。
guest

0

PostViewController

import UIKit class PostViewController: UIViewController, UITextFieldDelegate, UIPageViewControllerDataSource { @IBOutlet weak var bgAnimationView: UIView! @IBOutlet weak var emotionImage: UIImageView! let sboard: UIStoryboard? = UIStoryboard(name:"Main", bundle:nil) var pageViewControllers: [UIViewController] = [] var defaultStampImageNames: [String] = [] var myStampImageNames: [String] = [] var selectedImage: UIImage? { didSet{ self.emotionImage!.image = self.selectedImage self.emotionImage.setNeedsLayout() } } func setup() { // stamp画像の取得 defaultStampImageNames = ["heart_icon", "heart_icon"] myStampImageNames = ["heart_icon", "heart_icon"] } override func viewDidLoad() { super.viewDidLoad() setup() //スタンプ選択フィールドのページング実装 let defaultStampViewController: DefaultStampViewController = sboard!.instantiateViewController(withIdentifier: "DefaultStampViewController") as! DefaultStampViewController //スタンプ画像をコレクションビューに設定 defaultStampViewController.stampImages = defaultStampImageNames let myStampViewController: MyStampViewController = sboard!.instantiateViewController(withIdentifier: "MyStampViewController") as! MyStampViewController //スタンプ画像をコレクションビューに設定 myStampViewController.stampImages = myStampImageNames //UIPageViewControllerの取得 let pageViewController:UIPageViewController? = children[0] as? UIPageViewController //dataSourceに自分自身を設定 pageViewController?.dataSource = self pageViewControllers = [defaultStampViewController,myStampViewController] //UIPageViewControllerに表示対象を設定 pageViewController?.setViewControllers([pageViewControllers[0]], direction: .forward, animated: false, completion: nil) //postviewcontrollerを受け渡す defaultStampViewController.postViewController = self } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.view.backgroundColor = UIColor(hex: "FEC82A") startBackgroundAnimation() } //ページコントローラーの処理 func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController:UIViewController) -> UIViewController? { //右にスワイプした場合に表示したいviewControllerを返す //ようはページを戻す let index = pageViewControllers.index(of: viewController) if index == 0 { return nil } else { return pageViewControllers[index!-1] } } //ページコントローラーの処理 func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { //左にスワイプした場合に表示したいviewControllerを返す //ようはページを進める let index = pageViewControllers.index(of: viewController) if index == pageViewControllers.count-1 { return nil } else { return pageViewControllers[index!+1] } } //リターンを押されたとき func textFieldShouldReturn(_ textField: UITextField) -> Bool { return true } //背景アニメーション func startBackgroundAnimation() { let bgImage = UIImage.init(named: "background_icon")! bgAnimationView.backgroundColor = UIColor.init(patternImage: bgImage) bgAnimationView.frame.size = CGSize(width: view.frame.width + bgImage.size.width, height: view.frame.height + bgImage.size.height) let startOrigin = CGPoint(x: -bgImage.size.width, y: 0) let endOrigin = CGPoint(x: 0, y: -bgImage.size.height) bgAnimationView.frame.origin = startOrigin UIView.animate(withDuration: 1.3, delay: 0.0, options: [.repeat, .curveLinear], animations:{ self.bgAnimationView.frame.origin = endOrigin }, completion: nil) } //閉じる @IBAction func back(_ sender: Any) { dismiss(animated: true, completion: nil) } }

### DefaultStampViewController

import UIKit private let reuseIdentifier = "defaultStamp" class DefaultStampViewController: UICollectionViewController { var stampImages: [String] = [] var postViewController: PostViewController? override func viewDidLoad() { super.viewDidLoad() // Uncomment the following line to preserve selection between presentations // self.clearsSelectionOnViewWillAppear = false // Register cell classes // Do any additional setup after loading the view. } // MARK: UICollectionViewDataSource override func numberOfSections(in collectionView: UICollectionView) -> Int { // #warning Incomplete implementation, return the number of sections return 1 } override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of items return stampImages.count } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell :DefaultStampViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! DefaultStampViewCell let cellImg = UIImage(named: stampImages[indexPath.item]) cell.stampImg.image = cellImg cell.backgroundColor = UIColor.clear return cell } override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let selectedImage = UIImage(named: stampImages[indexPath.item])! postViewController!.selectedImage = selectedImage } }

投稿2019/02/25 04:16

shima_shima

総合スコア16

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問