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

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

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

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

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

1回答

748閲覧

フォトライブラリで選択した画像を、遷移後のimageViewに表示させたいです。

magiee

総合スコア28

Xcode

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

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2020/05/14 07:23

現状のswiftの動き

①textFieldをタップすると、下からpickerViewが開く。
②pickerViewの項目から"Photo"をタップするとフォトライブラリが開き、選択した画像が、遷移前のimageViewに表示される。
また、”Photo”以外の項目を選ぶと、Assets.xcassetsに登録した画像が、遷移前のimageViewに表示される。
③画面遷移後、Assets.xcassetsに登録した画像であれば、画面をタップすると画像が表示される。

実現したいこと

②のフォトライブラリで選択した画像も、画面遷移後に表示させたいです。

ご教授のほどよろしくお願いします。

該当のソースコード

import UIKit class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UINavigationControllerDelegate, UIImagePickerControllerDelegate { func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return 5 } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return data[row] } // PickerViewで選択が完了した際に呼ばれるメソッド func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { textField.text = data[row] result.text = data[row] if ( textField.text == "haru"){ sampleView.image = UIImage(named: "haru") } if ( textField.text == "natsu"){ sampleView.image = UIImage(named: "natsu") } if ( textField.text == "aki"){ sampleView.image = UIImage(named: "aki") } if ( textField.text == "huyu"){ sampleView.image = UIImage(named: "huyu") } } //画像が選択された時に呼ばれるメソッド //ライブラリが閉じると、遷移前のimageViewに表示される。 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { // 選択された画像を取得 if let myImage = info[.originalImage] as? UIImage { // 遷移前の画面に画像を表示する sampleView.image = myImage } // イメージピッカーを消す self.dismiss(animated: true, completion: nil) } //画像選択がキャンセルされた時に呼ばれる. func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { // イメージピッカーを消す self.dismiss(animated: true, completion: nil) } @IBOutlet weak var textField: UITextField! @IBOutlet weak var result: UILabel! var pickerView = UIPickerView() var data = ["haru", "natsu", "aki","huyu","Photo"] override func viewDidLoad() { super.viewDidLoad() createPickerView() } func createPickerView() { pickerView.delegate = self textField.inputView = pickerView // toolbar let toolbar = UIToolbar() toolbar.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 44) let doneButtonItem = UIBarButtonItem(title: "決定", style: .done, target: self, action: #selector(ViewController.donePicker)) let flexibleItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) toolbar.setItems([flexibleItem,doneButtonItem], animated: true) textField.inputAccessoryView = toolbar } @objc func donePicker() { textField.endEditing(true) // 以下の条件分岐を追加 if ( textField.text == "Photo") { // ここに、ボタン押下で UIImagePickerController() を表示させた時の処理を記載する func photoLibraryButton(_ sender: Any) { } // インスタンス生成 myImagePicker = UIImagePickerController() // デリゲート設定 myImagePicker.delegate = self //ここでイメージピッカーを表示させる。 present(myImagePicker, animated: true, completion: nil) } } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { textField.endEditing(true) if ( textField.text == "Photo") { func photoLibraryButton(_ sender: Any) { } // インスタンス生成 myImagePicker = UIImagePickerController() // デリゲート設定 myImagePicker.delegate = self //ここでイメージピッカーを表示させる。 present(myImagePicker, animated: true, completion: nil) } } var myImagePicker: UIImagePickerController! @IBOutlet weak var sampleView: UIImageView! @IBAction func nextButton(_ sender: Any) { performSegue(withIdentifier: "playPage", sender: nil) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let nextVC = segue.destination as? SecondViewController { nextVC.imageName = result.text } } }

###遷移後のコード

import UIKit class SecondViewController: UIViewController { var imageName: String! override func viewDidLoad() { super.viewDidLoad() // 前のページで値が入った imageName を表示する print(imageName!) } @IBAction func addImage(_ sender: UITapGestureRecognizer) { // UIImage の引数として imageName を渡す let mark = UIImageView(image: UIImage(named: imageName)) mark.frame = CGRect(x: 0, y: 0, width: 100, height: 100) // UIImageViewの中心座標をタップされた位置に設定 mark.center = sender.location(in: self.view) // UIImageViewを追加 self.view.addSubview(mark) } }

使用している言語

swift
Xvode 11.4

ご教授のほど、よろしくお願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

遷移前の画面で

swift

1override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 2 if let nextVC = segue.destination as? SecondViewController { 3 nextVC.imageName = result.text 4 } 5 }

という処理を行い値渡し(遷移後のクラスのプロパティに値を代入)しているので、同じように適切なプロパティを準備し UIImage を渡した上、遷移後の適切なタイミングでその画像を表示すればいいと思います。


全体的な流れを改めて見たのですが、

②pickerViewの項目から"Photo"をタップするとフォトライブラリが開き、選択した画像が、遷移前のimageViewに表示される。
また、”Photo”以外の項目を選ぶと、Assets.xcassetsに登録した画像が、遷移前のimageViewに表示される。

ということから、「遷移後に表示したい画像はimageViewに表示される」という前提を立てれば、遷移時に imageView.imageだけ渡せばよい、ということになります。

そうすると、

③画面遷移後、Assets.xcassetsに登録した画像であれば、画面をタップすると画像が表示される。

についてはアセットから読み直さず、遷移時に渡されたデータをそのまま使うということにすれば、多少すっきりとかけそうな気がしました。

そうすれば、

実現したいこと:②のフォトライブラリで選択した画像も、画面遷移後に表示させたいです。

は上記(3)のためのコードと共通化することができます。

つまり、

import UIKit class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UINavigationControllerDelegate, UIImagePickerControllerDelegate { // 中略 @IBAction func nextButton(_ sender: Any) { // 画像がセットされている時だけperformSegueを実行する if sampleView.image != nil { performSegue(withIdentifier: "playPage", sender: nil) } } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let nextVC = segue.destination as? SecondViewController { // ファイル名ではなく、画像データを渡す nextVC.displayImage = sampleView.image } } } class SecondViewController: UIViewController { // 画像データを受け取る変数 var displayImage: UIImage! override func viewDidLoad() { super.viewDidLoad() } @IBAction func addImage(_ sender: UITapGestureRecognizer) { // MARK: 渡された画像データから ImageView を作成する let mark = UIImageView(image: displayImage) // 以下略 } }

とすればいいと思います。

投稿2020/05/14 09:45

編集2020/05/17 09:20
TsukubaDepot

総合スコア5086

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

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

magiee

2020/05/14 10:41

遷移前の「prepare」のところに、 nextVC.photoImage = result.text を追加。 遷移後に var photoImage: UIImage! を追加するという考え方で良いのでしょうか?
TsukubaDepot

2020/05/14 11:09

まずはやってみるのがいいと思います(それが一番確実ですし、身につきます。考えることは大切ですが、考えすぎて手が止まるのも良くないと思います)。 ただし、上記の方法だと nextVC.photoImage = result.text のところでコンパイル前にエラーが出ると思います。 それは、 photoImage は UIImage 型 result.text は String型 と型が違うからです。 一方、 sampleView.image は何型で、何が入っていると思いますか? ご自身で書かれたコードだと、ピッカービューで画像を選んだ後にこのプロパティに画像を入れていると思います(pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)の中)。 そこをきちんと読み直せば、何型か、また何を渡せばいいのか分かってくるかと思います。
magiee

2020/05/14 13:36

sampleView は UIImage型だと思います。 nextVC.photoImage = sampleView.image にして、 遷移後 var photoImage: UIImage! にする必要があると思います。 また、 @IBAction func addImage( のところでは、String型をUIImage型に変換していますが、 今回のsampleViewから渡した型はすでに、UIImage型なので、そのまま使えるのでは無いかと、考えられます。 以上のことから、 @IBAction func addImage(_ sender: UITapGestureRecognizer) { の所に、 sampleview.image = UIImage(named: photoImage) というような形で記載すればいいのでは無いかと、考えているのですが、 sampleviewは、遷移前に定義したものなので、間違いっというのは、分かります。 しかし、代わりとなるようなコードを、何度もやってみてはいるのですが、全くうまくいきません。 どこから間違っているのでしょうか?
TsukubaDepot

2020/05/14 13:40

sampleview.image = UIImage(named: photoImage) 上記のコードですが、UIImage(named:)の引数はString型だったと思います。 つまり、画像名を指定してUIImageを作っているわけです。 が、今回の場合、photoImageという変数に既に画像データが入っているわけなので、 @IBAction func addImage(_ sender: UITapGestureRecognizer) { sampleview.image = photoImage とすれば大丈夫だと思いますが、いかがでしょうか。
magiee

2020/05/14 14:56

@IBAction func addImage(_ sender: UITapGestureRecognizer) { sampleView.image = photoImage とすると、Use of unresolved identifier 'sampleView' というエラーが出てしまいます。 sampleViewを定義しないといけないと思うのですが、うまくいきません。
TsukubaDepot

2020/05/14 22:37

ごめんなさい、本文の方をよく見ていませんでした。 遷移後の画面では、もともとは let mark = UIImageView(image: UIImage(named: imageName)) このようにして送られてきたイメージ名からUIImageを作っていましたが、今回はUIImageがそのまま送られてくるので let mark = UIImageView(image: photoImage) とすることになります。
magiee

2020/05/14 23:22

教えていただきありがとうございました。動かすことができました。 下記のコードで問題なく、動かすことができてはいるのですが、もっとシンプルにかけたり、追加した方がいいコード等ありましたら、教えていただけないでしょうか? @IBAction func addImage(_ sender: UITapGestureRecognizer) { // UIImage の引数として imageName を渡す let photoView = UIImageView(image: photoImage) photoView.frame = CGRect(x: 0, y: 0, width: 100, height: 100) photoView.center = sender.location(in: self.view) self.view.addSubview(photoView) // UIImage の引数として imageName を渡す let mark = UIImageView(image: UIImage(named: imageName)) mark.frame = CGRect(x: 0, y: 0, width: 100, height: 100) mark.center = sender.location(in: self.view) self.view.addSubview(mark) }
TsukubaDepot

2020/05/15 01:29

上記のコードですが、前の画面で選ばれたUIimageと、前の画面から渡されたきたimageNameの両方の画像を使うことになっていますが、magieeさんの想定ではそれで良いのでしょうか。 両方の画像とも追加するのであれば、これ以上シンプルにはできませんし、する必要もないと思います。 もし、どちらか片一方でよいのであれば、不必要な方を消すことになります。 最初のご質問だと、「フォトライブラリで選択した画像を、遷移後のimageViewに表示させたいです。」ということでしたので、選ばれた画像だけ表示すれば良いと解釈したのですが、実際はどうなのでしょうか。 まずは、ここをきちんと確定した方がいいと思います(私が解釈できない以上に、magieeさんがコードとしてどのように表現すればいいのか確定することができないはずです)。
magiee

2020/05/15 12:27

求める物としては、前の画面で選ばれた項目がUIImageの場合と、imageNameの場合の2つを考えており、上記のコードですと、photoViewとmarkの2つで分かれており、if分的な形(?)となっている為、一応求めている動きとなってはいます。本来であれば、if文を使って、photoViewの場合、markの場合というコードを記載するのかもしれません。。。
TsukubaDepot

2020/05/17 09:21

改めてご質問内容、特に実現したいことを見直して、少しすっきりとした処理に書き換えてみました。 回答本文に追記してありますので、ご参照いただければと思います。
magiee

2020/05/17 10:55

丁寧に回答していただきまして、ありがとうございます! とても分かりやすく、すっきりしたコードになりました。 画像データを渡すことで、元々のファイル名を下に画面遷移後のimageViewに渡していたコードが不要となったということですね。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問