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

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

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

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

Swift

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

Q&A

0回答

1275閲覧

【Swift】カメラロールから取得した画像の保持の方法

maroon.maroon

総合スコア0

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/08/16 12:31

編集2020/08/16 23:26

前提・実現したいこと

I
Swift初心者です。
勉強のため、iPhoneで使える簡単なメモアプリを作成しています。
テキスト及びカメラロールから取得した画像をTableViewに追加できる、というものです。

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

起動時にはViewControllerが表示され、こちらがメモの一覧が表示されるページになります。
ViewController上の「+」ボタンを押すとTableViewControllerの画面が表示され、
TableViewControllerにテキストおよびカメラロールから取得した画像を入力、
「save」を押すとテキストと画像がTableViewController保存され、再びViewControllerに戻るという動きを考えています。
この際、TableViewControllerに入力されたテキスト、画像は保持されていることを想定しています。

現在発生している問題は、「save」を押してViewControllerに戻り、再度TableViewControllerを表示させると、カメラロールから取得した画像が表示されず、テキストのみ入力内容が保持されているという状況です。
テキストについては「userDefault」に保存することができたのですが、カメラロールから取得した画像を保持させておく方法がわからずに困っております。
下記「試したこと」にある画像の保持を目的としたコードを書いたのですが、変わらず画像は保持されておりません。

エラーメッセージ ```エラーメッセージは出ていません。 ### 該当のソースコード ```Swift ソースコード 【ViewController】 import UIKit import SwiftUI class ViewController: UIViewController,UIImagePickerControllerDelegate, UINavigationControllerDelegate { var memo: String? @IBOutlet weak var memoTextField: UITextField! @IBOutlet weak var saveButton: UIBarButtonItem! @IBOutlet weak var imageView: UIImageView! let userDefaults = UserDefaults.standard //画像保持のため追加 var saveArray: Array! = [NSData]() var image: UIImage! override func viewDidLoad() { super.viewDidLoad() self.saveButton.isEnabled = false if let memo = self.memo{ self.memoTextField.text = memo self.navigationItem.title = "Edit Memo" } let memo = self.memoTextField.text ?? "" self.saveButton.isEnabled = !memo.isEmpty // Do any additional setup after loading the view. } @IBAction func toAlbumBtn(_ sender: Any) { let picker = UIImagePickerController() picker.sourceType = .photoLibrary picker.delegate = self present(picker, animated: true) self.present(picker, animated: true, completion: nil) } func imagePickerController(_ picker: UIImagePickerController,didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){ if let selectedImage = info[.originalImage]as? UIImage{ imageView.image = selectedImage } self.dismiss(animated: true) //self.userDefaults.set(self.imageView,forKey: "image") } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { self.dismiss(animated: true, completion: nil) } @IBAction func memoTextFieldChanged(_ sender: Any) { let memo = self.memoTextField.text ?? "" self.saveButton.isEnabled = !memo.isEmpty } @IBAction func cancel(_ sender: Any) { if self.presentingViewController is UINavigationController{ self.dismiss(animated: true, completion: nil) } else { self.navigationController?.popViewController(animated: true) } } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard let button = sender as? UIBarButtonItem,button === self.saveButton else { return } self.memo = self.memoTextField.text ?? "" } } 【TableViewController】 import UIKit import SwiftUI class babyTableViewController: UITableViewController { let userDefaults = UserDefaults.standard var memos = [String]() var saveArray:Array! = [NSData]() var image: UIImage! @IBAction func unwindToMemoList(sender: UIStoryboardSegue){ guard let sourceVC = sender.source as? babyViewController, let memo = sourceVC.memo else { return } if let selectedIndexPath = self.tableView.indexPathForSelectedRow { self.memos[selectedIndexPath.row] = memo } else { self.memos.append(memo) } self.userDefaults.set(self.memos, forKey: "memos") self.tableView.reloadData() } override func viewDidLoad() { super.viewDidLoad() if self.userDefaults.object(forKey: "memos") != nil { self.memos = self.userDefaults.stringArray(forKey: "memos")! } else { self.memos = [] } //画像保存のために追加 func sendSaveImage() { //NSData型にキャスト let data = image.pngData() as NSData? if let imageData = data { saveArray.append(imageData) userDefaults.set(saveArray, forKey: "saveImage") userDefaults.synchronize() } } //画像保存のために追加 func defaultsArray() { //UserDefaultsの中身が空でないことを確認 if userDefaults.object(forKey: "saveImage") != nil { let objects = userDefaults.object(forKey: "saveImage") as? NSArray //配列としてUserDefaultsに保存した時の値と処理後の値が変わってしまうのでremoveAll() saveArray.removeAll() for data in objects! { saveArray.append(data as! NSData) } } tableView.reloadData() } } // MARK: - Table view data source override func numberOfSections(in tableView: UITableView) -> Int { // #warning Incomplete implementation, return the number of sections return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of rows return self.memos.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "babyTableViewCell", for: indexPath) // Configure the cell... cell.textLabel?.text = self.memos[indexPath.row] return cell } override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { if editingStyle == .delete { // Delete the row from the data source self.memos.remove(at: indexPath.row) self.userDefaults.set(self.memos, forKey: "memos") tableView.deleteRows(at: [indexPath], with: .fade) } else if editingStyle == .insert { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard let identifier = segue.identifier else { return } if identifier == "editMemo" { let memoVC = segue.destination as! babyViewController memoVC.memo = self.memos[(self.tableView.indexPathForSelectedRow?.row)!] } } }

試したこと

【TableViewController】内にあります、
func sendSaveImage() {
//NSData型にキャスト
let data = image.pngData() as NSData?
if let imageData = data {
saveArray.append(imageData)

userDefaults.set(saveArray, forKey: "saveImage") userDefaults.synchronize() } } //画像保存のために追加 func defaultsArray() { //UserDefaultsの中身が空でないことを確認 if userDefaults.object(forKey: "saveImage") != nil { let objects = userDefaults.object(forKey: "saveImage") as? NSArray //配列としてUserDefaultsに保存した時の値と処理後の値が変わってしまうのでremoveAll() saveArray.removeAll() for data in objects! { saveArray.append(data as! NSData) } } tableView.reloadData() }

を画像の保持目的で追加しました。

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

Xcode Version 11.5

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

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

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

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

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

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

TsukubaDepot

2020/08/16 12:44

ソースコードは ```Swift ソースコード ``` と書かれた部分の「ソースコード」の部分に貼り付けていただけますでしょうか(既に提示されたソースコード先頭行の前に ```Swift を置き、末尾の次の行に ```を置く方法で構いません)。整形された方が見やすく、またコピーして再現させることも容易となりますので、よろしくお願いいたします。
maroon.maroon

2020/08/16 13:22

大変申し訳ございません。 ご指摘ありがとうございます。 修正致しましたので、どうぞよろしくお願い致します。
TsukubaDepot

2020/08/16 22:14

ViewControllerと babyTableViewController の関係がよくわからないのですが、起動時に表示されるのはどちらの ViewController で、どのような操作を行えば何が行えるのか、また行えないことについて、どの ViewController で何を行ったら、何ができないのかご質問本文に追記していただけないでしょうか。
maroon.maroon

2020/08/16 23:27

何度も申し訳ありません。 詳細追記致しましたので、どうぞよろしくお願い致します。
TsukubaDepot

2020/08/17 03:30

> 起動時にはViewControllerが表示され、こちらがメモの一覧が表示されるページになります。 > ViewController上の「+」ボタンを押すとTableViewControllerの画面が表示され、 > TableViewControllerにテキストおよびカメラロールから取得した画像を入力、 >「save」を押すとテキストと画像がTableViewController保存され、再びViewControllerに戻るという動きを考えています。 > この際、TableViewControllerに入力されたテキスト、画像は保持されていることを想定しています。 とありますが、コードを拝見する限り違っているように見えます。 最初に表示されるのは babyTableViewController(UITableViewController のサブクラス)が表示され、なんらかのボタンを押すと ViewController が表示される、というのが正しい流れなのではないでしょうか。 「こちらがメモの一覧が表示されるページ」とありますが、一覧を表示させるのであれば一般的には TableView を使うことが多いため、それから考えてもご説明の内容だと矛盾が生じます。 また、「TableViewControllerにテキストおよびカメラロールから取得した画像を入力」とありますが、コードと比較するとその操作は ViewController で行っているようですので、これもやはりご説明と矛盾しています。 ところで、babyTableViewController の unwindToMemoList(sender:) で babyViewController というクラス名が出てきていますが、それはどれに該当するのでしょうか。流れや参照しているプロパティから推測するとViewController のことかと思いますが、それだとクラス名が一致しませんし、コンパイルも通りません。 加えて、babyTableViewController の viewDidLoad() で関数が2つ定義されているようですが、これはどのような理由で関数内に関数を定義されているのでしょうか。 文法的には誤りではありませんが、この目的では実質意味をなしていないかと思われます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問