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

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

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

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

Q&A

解決済

1回答

393閲覧

DKimageControllerで画像を取得し、画面遷移先に表示したい

coco7777

総合スコア8

Swift

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

0グッド

0クリップ

投稿2022/07/04 09:20

編集2022/07/07 07:37

初学者です。
DKimageControllerで複数枚の画像を取得して、画面遷移先に表示したいです。
画面遷移先はTableViewのCellにあるUIImageViewです。
取得した複数の画像のうち1枚をUIImageViewに表示したいです。(残りの画像はこの次の遷移で表示する)
以下のサイトを参考にコードを書いたのですが、「選択」ボタンを押した後の処理をどこにどのように書けばよいのかわからず困っています。
https://qiita.com/dkazu6393/items/4374b5f46d965f4decd9 
https://teratail.com/questions/326346 

cellにはtext Fieldの値なども一緒に渡して遷移したいので、ユーザーデフォルトを使いたいです。
有識者の方回答お願いします。

swift

1import UIKit 2import DKImagePickerController 3 4 5class hennsyuViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UITextFieldDelegate, UITextViewDelegate { 6 7 var completButtonItem:UIBarButtonItem! 8 9 @IBOutlet weak var textField: UITextView! 10 @IBOutlet weak var dateField: UITextField! 11 @IBOutlet weak var hyoukaField: UITextField! 12 @IBOutlet weak var addressField: UITextField! 13 @IBOutlet weak var nameField: UITextField! 14 15 var photos: [UIImage] = [] 16 // 実際に選択された枚数 17 var selectedCount = 0 18 19 let pickerController = DKImagePickerController() 20 21 override func viewDidLoad() { 22 super.viewDidLoad() 23 24 dateField.delegate = self 25 hyoukaField.delegate = self 26 addressField.delegate = self 27 nameField.delegate = self 28 textField.delegate = self 29 30// checkpermission.checkCamera() 31 32 let appearance = UINavigationBarAppearance() 33 appearance.configureWithOpaqueBackground() 34 appearance.backgroundColor = .rgb(red: 173, green: 216, blue: 230) 35 navigationController?.navigationBar.tintColor = UIColor.white 36 //標準の高さ 37 navigationItem.standardAppearance = appearance 38 //ナビゲーションバーが透過する 39 navigationItem.scrollEdgeAppearance = appearance 40 //標準の文字の大きさ 41 navigationItem.compactAppearance = appearance 42 43 completButtonItem = UIBarButtonItem(title: "完了", style: .done, target: self, action: #selector(completButtonTapped(_:))) 44 self.navigationItem.rightBarButtonItem = completButtonItem 45 46 dateField.setUnderLine() 47 hyoukaField.setUnderLine() 48 addressField.setUnderLine() 49 nameField.setUnderLine() 50 51 52 let toolBar = UIToolbar() 53 toolBar.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 40) 54 let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil) 55 let kbDoneButton = UIBarButtonItem(title: "閉じる", style: .done, target: self, action:#selector(kbDoneTaped) ) 56 57 toolBar.items = [spacer,kbDoneButton] 58 59 textField.inputAccessoryView = toolBar 60 61 62 } 63 64 override func viewWillAppear(_ animated: Bool) { 65 super.viewWillAppear(animated) 66 67 NotificationCenter.default.addObserver(self, selector: #selector(hennsyuViewController.keyboardShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) 68 69 NotificationCenter.default.addObserver(self, selector: #selector(hennsyuViewController.keyboardHide(_:)), name: UIResponder.keyboardDidHideNotification, object: nil) 70 71 } 72 73 74 @IBAction func addImageButton(_ sender: Any) { 75 76 pickerController.maxSelectableCount = 5 77 //カメラモード、写真モードの選択 78 pickerController.sourceType = .photo 79 //キャンセルボタンの有効化 80 pickerController.showsCancelButton = true 81 82 pickerController.UIDelegate = CustomUIDelegate() 83 84// pickerController.didSelectAssets = { (assets: [DKAsset]) in 85// // ここでは一旦全削除する 86// self.photos.removeAll() 87// // assets に保存された枚数 88// self.selectedCount = assets.count 89// 90// for asset in assets { 91// // asset からのダウンロードは非同期(iCloudなどにアクセスするため) 92// asset.fetchFullScreenImage(completeBlock: { (image, info) in 93// // もし image が nil だったら早期リターン 94// guard let image = image else { 95// self.selectedCount -= 1 96// return 97// } 98// // photos に追加 99// self.photos.append(image) 100// }) 101// } 102// } 103 104 pickerController.modalPresentationStyle = .fullScreen 105 present(pickerController, animated: true, completion: nil) 106 107 } 108 109 110 111 func textFieldShouldReturn(_ textField: UITextField) -> Bool { 112 113 dateField.resignFirstResponder() 114 hyoukaField.resignFirstResponder() 115 addressField.resignFirstResponder() 116 nameField.resignFirstResponder() 117 118 return true 119 } 120 121 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){ 122 123 self.view.endEditing(true) 124 } 125 126 127 @objc func keyboardShow(_ notification: Notification){ 128 129 if !textField.isFirstResponder { 130 return 131 } 132 if self.view.frame.origin.y == 0 { 133 if let keyboardRect = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue { 134 self.view.frame.origin.y -= keyboardRect.height 135 } 136 } 137 } 138 139 @objc func keyboardHide(_ notification: Notification){ 140 141 if self.view.frame.origin.y != 0 { 142 self.view.frame.origin.y = 0 143 } 144 145 } 146 147 148 @objc func kbDoneTaped (_ sender:UIButton){ 149 150 self.view.endEditing(true) 151 152 } 153 154 //完了ボタンを押した時 155 @objc func completButtonTapped(_ sender: UIBarButtonItem){ 156 157// UserDefaults.standard.set(textField.text, forKey: "textView") 158// UserDefaults.standard.set(nameField.text, forKey: "nameField") 159// UserDefaults.standard.set(addressField.text, forKey: "addressField") 160// UserDefaults.standard.set(dateField.text, forKey: "dateField") 161// UserDefaults.standard.set(hyoukaField.text, forKey: "hyoukaField") 162 163 164 if let n = navigationController, 165 n.viewControllers[n.viewControllers.count - 2] is nikkiTableViewController { 166 167 // ①から遷移してきた場合は完了をタップしたことを表すフラグを設定します。 168 AppState.isEdited = true 169 170 } 171 navigationController?.popViewController(animated: true) 172 173 } 174}

swift

1import Foundation 2import DKImagePickerController 3 4class CustomUIDelegate:DKImagePickerControllerBaseUIDelegate { 5 6 override func createDoneButtonIfNeeded() -> UIButton { 7 let selectbutton = UIButton(type: UIButton.ButtonType.custom) 8 selectbutton.setTitle("選択", for: .normal) 9 selectbutton.setTitleColor(UINavigationBar.appearance().tintColor ?? self.imagePickerController.navigationBar.tintColor, for: .normal) 10 selectbutton.addTarget(self, action: #selector(selectTap), for: .touchUpInside) 11 return selectbutton 12 } 13 14 //写真選択超過時のアラートのカスタマイズ 15 override func imagePickerControllerDidReachMaxLimit(_ imagePickerController: DKImagePickerController) { 16 let alert = UIAlertController.init(title: "注意", message: "これ以上選択できません!", preferredStyle: .alert) 17 let okAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.cancel, handler: nil) 18 alert.addAction(okAction) 19 imagePickerController.present(alert, animated: true, completion: nil) 20 } 21 22 //cancelボタンのカスタマイズ 23 override func imagePickerController(_ imagePickerController: DKImagePickerController, showsCancelButtonForVC vc: UIViewController) { 24 let cancelButton = UIBarButtonItem() 25 cancelButton.title = "戻る" 26 cancelButton.style = .plain 27 cancelButton.action = #selector(imagePickerController.dismiss as () -> Void) 28 cancelButton.target = imagePickerController 29 vc.navigationItem.leftBarButtonItem = cancelButton 30 } 31@objc func selectTap() { 32 33 imagePickerController.dismiss(animated: true) 34 35 } 36 37 } 38

イメージ説明
イメージ説明

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2022/07/04 14:11

もっと詳しい方が回答してくださるかもしれませんが、 コメントしてみます・・ > 「選択」ボタンを押した後の処理をどこにどのように書けばよいのかわからず困っています。 現在コメントアウトになっているpickerController.didSelectAssetsの中に記述する感じになると思いました。 > cellにはtext Fieldの値なども一緒に渡して遷移したいので、ユーザーデフォルトを使いたいです。 UserDefaultsを使う方針が気になりました。 画像のデータは1つ2MBとかになりそうで、それが複数となるとUserDefaultsに適さないように思いました。 今回扱おうとしている画像データはアプリを終了しても保持しておきたい性質のものではないように感じましたので、 外部の領域に保存せずに、アプリの中のメモリ領域(プロパティなど?)に保持することで十分のように思いました。 *Swiftのお作法などに詳しくないですので、見当違いのことを書いてしまっていましたらごめんなさい https://ja.stackoverflow.com/questions/82821/userdefaults-に格納できるデータ容量の上限は > (機械翻訳)UserDefaultsクラスは、デフォルトシステムと対話するためのプログラムインターフェイスを提供します。デフォルトシステムを使用すると、ユーザーの好みに合わせてアプリの動作をカスタマイズすることができます。たとえば、ユーザーが好みの計測単位やメディアの再生速度を指定できるようにすることができます。アプリは、ユーザーのデフォルトデータベース内の一連のパラメーターに値を割り当てることで、これらの嗜好を保存します。パラメータがデフォルトと呼ばれるのは、起動時のアプリのデフォルト状態やデフォルトの動作方法を決定するために一般的に使用されるからです。 > https://developer.apple.com/documentation/foundation/userdefaults
hoshi-takanori

2022/07/04 14:55

xg63ex2b さんがお書きになってる通り、UserDefaults はアプリが終了して再起動された時に設定項目を保存するためのものです。 普通の画面遷移ではアプリは終了しないので、そもそも UserDefaults に保存する必要がありません。画面間で直接データを受け渡せば良いはず。
coco7777

2022/07/06 03:22

xg63ex2bさん、Hoshi-takanoriさん たびたび回答してくださりありがとうございます >現在コメントアウトになっているpickerController.didSelectAssetsの中に記述する感じになると思いました。 ありがとうございます、やってみます >xg63ex2b さんがお書きになってる通り、UserDefaults はアプリが終了して再起動された時に設定項目を保存するためのものです。 普通の画面遷移ではアプリは終了しないので、そもそも UserDefaults に保存する必要がありません。画面間で直接データを受け渡せば良いはず。 ユーザーデフォルトの用途を誤認しておりました。初期設定などを保存するときに用いるものなのですね。 勉強になりました。ありがとうございます。 今回、私は写真付きの日記アプリを作成したいのですが、データ保存は「Core Data」にすれば良いのでしょうか? 他に適している保存方法があれば教えていただきたいです よろしくおねがいします
hoshi-takanori

2022/07/06 03:37 編集

データを端末に保存する(他人と共有しない)なら、Core Data か Realm でしょうね。画像はどうするのが良いのかな…。頑張ってください。
退会済みユーザー

退会済みユーザー

2022/07/06 04:07

コメントありがとうございます。 > 今回、私は写真付きの日記アプリを作成したいのですが、データ保存は「Core Data」にすれば良いのでしょうか? 質問欄にある画面遷移の部分しか考えていないで前回のコメントをしてしまいました、ごめんなさい。 日記のデータ(写真データ含む)はアプリを終了しても保存しておきたいですので、最終的にはアプリの外部に保存になりますよね。 > 画像はどうするのが良いのかな…。 写真のバイナリのデータを「Core Data」(Realm?)に含めてしまうのか、 「Core Data」にはパスなどの情報だけ持たせておいて写真データはディレクトリに保存するのか、 どちらも面倒な部分はありそうですけれども・・ まとめて管理できるということで「Core Data」で良いのかもしれませんね。
coco7777

2022/07/06 06:13

xg63ex2bさん、Hoshi-takanoriさん 回答ありがとうございます >質問欄にある画面遷移の部分しか考えていないで前回のコメントをしてしまいました、ごめんなさい。 日記のデータ(写真データ含む)はアプリを終了しても保存しておきたいですので、最終的にはアプリの外部に保存になりますよね。 とんでもありません、何度も回答していただいてありがたい限りです Core Dateで良いということですね。知識が全然ないので調べてやってみます また詰まると思いますのでその際は質問させていただきます。 よろしくおねがいします
coco7777

2022/07/06 06:53

xg63ex2bさん  >pickerController.didSelectAssetsの中に記述する感じになると思いました。 Buttonを押して、ライブラリにアクセスするのですが追加した写真のように、1枚目の白い画面で選択し「完了」を押すと選択された画像が、2枚目に出てきて選択できるような二重構造になってます。 pickerController.didSelectAssetsの中にself.photos.append(image)があるのですが 配列『photos』は2枚目の画像(DKimageController?)に渡している配列という認識で間違いないでしょうか? それで present(pickerController, animated: true, completion: nil) によってpickerController(DKimageController)に遷移しているとすると その後に「選択」の処理を書かないといけないのではないかと思ったのですが、didSelectAssetsの中に記述する理由を教えていただけると嬉しいです。 didSelectAssetsのことを調べてみたのですが理解できるような記事がなく質問させていただきました。 何度も申し訳ありません
退会済みユーザー

退会済みユーザー

2022/07/06 08:16

コメントありがとうございます。 > 1枚目の白い画面で選択し「完了」を押すと選択された画像が、2枚目に出てきて選択できるような二重構造になってます。 ちょっと違う気がしますね・・ 選択は1回だけが正しい気がします。 `pickerController.modalPresentationStyle = .fullScreen` の行が不要なのでしょうか(削除してみるとか)。 あるいは `pickerController.UIDelegate = CustomUIDelegate()` の行が何か矛盾しているのでしょうか。 --- > 配列『photos』は2枚目の画像(DKimageController?)に渡している配列という認識で間違いないでしょうか? 現在はおそらく2枚目の選択の画面になるとは思うのですが、本来は選択は1回が正しいのかなと思います・・ --- > その後に「選択」の処理を書かないといけないのではないかと思ったのですが、didSelectAssetsの中に記述する理由を教えていただけると嬉しいです。 > /// The block is executed when the user presses the select button. > @objc public var didSelectAssets: ((_ assets: [DKAsset]) -> Void)? > (機械翻訳:ブロックは、ユーザーが選択ボタンを押すと実行されます。) > https://github.com/zhangao0086/DKImagePickerController#getting-started あらかじめdidSelectAssetsのところに処理を渡しておくと、 「選択」ボタンをタップしたときにDKImagePickerControllerがその処理を呼び出してくれると思います。 ですので、選択ボタンを押したときの処理はdidSelectAssetsのブロックに記述するのでOKと思います。
coco7777

2022/07/07 07:41 編集

回答ありがとうございます! pickerController.modalPresentationStyle = .fullScreen 部分がないとナビゲーションバーがうまく表示されなかったので上記した参考にしたサイトにはありませんが調べて追加してみました。この部分を削除しても変化なかったです。 >`pickerController.UIDelegate = CustomUIDelegate()` の行が何か矛盾しているのでしょうか。 助言ありがとうございます もう少し調べてみます >あらかじめdidSelectAssetsのところに処理を渡しておくと、 「選択」ボタンをタップしたときにDKImagePickerControllerがその処理を呼び出してくれると思います。 ですので、選択ボタンを押したときの処理はdidSelectAssetsのブロックに記述するのでOKと思います。 そう言うことなのですね、参考にしたサイトにも解説など書かれてなくて意味がわかっていませんでした、、 ありがとうございます  CustomUIDelegate の「選択」ボタンの部分をselectbutton.addTarget(self, action: #selector(selectTap), for: .touchUpInside)に変更して @objc 内に imagePickerController.dismiss(animated: true)を記載してみました。 一応閉じるようにはなったのですが、これだと問題はありますでしょうか? 自分でやってみたので適切かどうかわかっていないです、、 
退会済みユーザー

退会済みユーザー

2022/07/07 10:21

> 一応閉じるようにはなったのですが、これだと問題はありますでしょうか? それをしないといけない状況なのですね・・ ちょっと違う感じがしますね。 一旦、カスタマイズのUIなどはコメントアウトなどしておいて、 Getting Startedにあるように、単純な実装から始めてみた方が良いかもしれません。 多分、これだけでとりあえず動くのかなと思うのですが、どうでしょうか。 ``` let pickerController = DKImagePickerController() pickerController.didSelectAssets = { (assets: [DKAsset]) in print("didSelectAssets") print(assets) } self.presentViewController(pickerController, animated: true) {} ``` Getting Started https://github.com/zhangao0086/DKImagePickerController#getting-started
coco7777

2022/07/09 12:48

xg63ex2bさん 回答 ありがとうございます おしゃるとうりにUIなどコメントアウトして、教えていただいたコードを書くと動いてくれました ありがとうございます  閉じてはくれたのですが、2重にカメラロール?が出てくるのは改善されませんでした。 カスタムUIが原因ではないようですね、、、
退会済みユーザー

退会済みユーザー

2022/07/09 15:44

> 閉じてはくれたのですが、2重にカメラロール?が出てくるのは改善されませんでした。 再現確認してみたら状況がわかりました。 (CocoaPodsを使ったことがなかったので怠っていました・・) https://support.apple.com/ja-jp/guide/iphone/iph251e92810/ios https://news.mynavi.jp/article/20201128-iphone_why/ 最初にアクセス許可を求められた時に「写真を選択…」(Select Photos…)にすると、 一度iOSの機能として写真を選択して、その後、選択した写真だけをアプリが操作できるようになるみたいです。 (悪意のあるアプリが勝手にデータを奪い取ることができないための仕組みでしょうか) 「設定」>「プライバシー」>「写真」からアプリに「すべての写真」の許可を与えることで iOSの機能としての写真選択画面は表示しないようにできるみたいです。 iOSの動向に疎いために誤ったコメントをしてしまい、ごめんなさい。
coco7777

2022/07/10 02:04

xg63ex2bさん 回答ありがとうございます それが原因だったのですね、、自分で調べてはいたのですが全然わからなかったのでとてもありがたいです >iOSの動向に疎いために誤ったコメントをしてしまい、ごめんなさい。 とんでもないです いろいろな角度からアドバイスをいただけてありがたい限りです。 ありがとうございます 教えていただいたことを参考に自分ですすめてみます。データ保存などわからないことが多々ありますので また質問をさせていただくと思います その際はよろしくおねがいします。 ベストアンサーに選択したいのでよろしければ回答欄に何か記載をおねがいします
guest

回答1

0

ベストアンサー

「選択」ボタンを押した後の処理をどこにどのように書けばよいのかわからず困っています。

現在コメントアウトになっているpickerController.didSelectAssetsの中に記述する感じになると思いました。

CustomUIDelegate の「選択」ボタンの部分をselectbutton.addTarget(self, action: #selector(selectTap), for: .touchUpInside)に変更して @objc 内に imagePickerController.dismiss(animated: true)を記載してみました。 一応閉じるようにはなったのですが、これだと問題はありますでしょうか?

これだとdidSelectAssetsを呼び出してくれないかもしれませんね。
DKImagePickerController.doneメソッドがあるみたいですので、このメソッドを呼び出す感じにすると良いみたいです。
(doneメソッドの中からdidSelectAssetsを呼び出してくれるのだと思います)
次のような感じになると思います。
button.addTarget(self.imagePickerController, action: #selector(DKImagePickerController.done), for: .touchUpInside)

UIの基本の処理で何をしているか、ソースを見てみると良いかもしれません。
https://github.com/zhangao0086/DKImagePickerController/blob/9a00af43ad9205b4b537bd02e257b2fbe778ad3e/Sources/DKImagePickerController/DKImagePickerControllerBaseUIDelegate.swift#L97


cellにはtext Fieldの値なども一緒に渡して遷移したいので、ユーザーデフォルトを使いたいです。

UserDefaultsは画像の保存には適していないみたいです。
https://developer.apple.com/documentation/foundation/userdefaults
Core DataかRealmを検討してみると良いみたいです。

コメント欄で簡単に画像もCore Dataに含めてしまって良いみたいに書いてしまいましたが、
どちらを選択しても面倒な部分はありますので、
デメリットも認識しておいた方が良いと思いました。
https://qiita.com/7coco/items/1706a561131363d2c418

投稿2022/07/10 05:26

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

coco7777

2022/07/11 08:08

回答ありがとうございます いただいた回答を参考に進めて見ようと思います
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問