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

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

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

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

解決済

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

coco7777
coco7777

総合スコア8

Swift

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

1回答

0リアクション

0クリップ

234閲覧

投稿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

import UIKit import DKImagePickerController class hennsyuViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UITextFieldDelegate, UITextViewDelegate { var completButtonItem:UIBarButtonItem! @IBOutlet weak var textField: UITextView! @IBOutlet weak var dateField: UITextField! @IBOutlet weak var hyoukaField: UITextField! @IBOutlet weak var addressField: UITextField! @IBOutlet weak var nameField: UITextField! var photos: [UIImage] = [] // 実際に選択された枚数 var selectedCount = 0 let pickerController = DKImagePickerController() override func viewDidLoad() { super.viewDidLoad() dateField.delegate = self hyoukaField.delegate = self addressField.delegate = self nameField.delegate = self textField.delegate = self // checkpermission.checkCamera() let appearance = UINavigationBarAppearance() appearance.configureWithOpaqueBackground() appearance.backgroundColor = .rgb(red: 173, green: 216, blue: 230) navigationController?.navigationBar.tintColor = UIColor.white //標準の高さ navigationItem.standardAppearance = appearance //ナビゲーションバーが透過する navigationItem.scrollEdgeAppearance = appearance //標準の文字の大きさ navigationItem.compactAppearance = appearance completButtonItem = UIBarButtonItem(title: "完了", style: .done, target: self, action: #selector(completButtonTapped(_:))) self.navigationItem.rightBarButtonItem = completButtonItem dateField.setUnderLine() hyoukaField.setUnderLine() addressField.setUnderLine() nameField.setUnderLine() let toolBar = UIToolbar() toolBar.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 40) let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil) let kbDoneButton = UIBarButtonItem(title: "閉じる", style: .done, target: self, action:#selector(kbDoneTaped) ) toolBar.items = [spacer,kbDoneButton] textField.inputAccessoryView = toolBar } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) NotificationCenter.default.addObserver(self, selector: #selector(hennsyuViewController.keyboardShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(hennsyuViewController.keyboardHide(_:)), name: UIResponder.keyboardDidHideNotification, object: nil) } @IBAction func addImageButton(_ sender: Any) { pickerController.maxSelectableCount = 5 //カメラモード、写真モードの選択 pickerController.sourceType = .photo //キャンセルボタンの有効化 pickerController.showsCancelButton = true pickerController.UIDelegate = CustomUIDelegate() // pickerController.didSelectAssets = { (assets: [DKAsset]) in // // ここでは一旦全削除する // self.photos.removeAll() // // assets に保存された枚数 // self.selectedCount = assets.count // // for asset in assets { // // asset からのダウンロードは非同期(iCloudなどにアクセスするため) // asset.fetchFullScreenImage(completeBlock: { (image, info) in // // もし image が nil だったら早期リターン // guard let image = image else { // self.selectedCount -= 1 // return // } // // photos に追加 // self.photos.append(image) // }) // } // } pickerController.modalPresentationStyle = .fullScreen present(pickerController, animated: true, completion: nil) } func textFieldShouldReturn(_ textField: UITextField) -> Bool { dateField.resignFirstResponder() hyoukaField.resignFirstResponder() addressField.resignFirstResponder() nameField.resignFirstResponder() return true } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){ self.view.endEditing(true) } @objc func keyboardShow(_ notification: Notification){ if !textField.isFirstResponder { return } if self.view.frame.origin.y == 0 { if let keyboardRect = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue { self.view.frame.origin.y -= keyboardRect.height } } } @objc func keyboardHide(_ notification: Notification){ if self.view.frame.origin.y != 0 { self.view.frame.origin.y = 0 } } @objc func kbDoneTaped (_ sender:UIButton){ self.view.endEditing(true) } //完了ボタンを押した時 @objc func completButtonTapped(_ sender: UIBarButtonItem){ // UserDefaults.standard.set(textField.text, forKey: "textView") // UserDefaults.standard.set(nameField.text, forKey: "nameField") // UserDefaults.standard.set(addressField.text, forKey: "addressField") // UserDefaults.standard.set(dateField.text, forKey: "dateField") // UserDefaults.standard.set(hyoukaField.text, forKey: "hyoukaField") if let n = navigationController, n.viewControllers[n.viewControllers.count - 2] is nikkiTableViewController { // ①から遷移してきた場合は完了をタップしたことを表すフラグを設定します。 AppState.isEdited = true } navigationController?.popViewController(animated: true) } }

swift

import Foundation import DKImagePickerController class CustomUIDelegate:DKImagePickerControllerBaseUIDelegate { override func createDoneButtonIfNeeded() -> UIButton { let selectbutton = UIButton(type: UIButton.ButtonType.custom) selectbutton.setTitle("選択", for: .normal) selectbutton.setTitleColor(UINavigationBar.appearance().tintColor ?? self.imagePickerController.navigationBar.tintColor, for: .normal) selectbutton.addTarget(self, action: #selector(selectTap), for: .touchUpInside) return selectbutton } //写真選択超過時のアラートのカスタマイズ override func imagePickerControllerDidReachMaxLimit(_ imagePickerController: DKImagePickerController) { let alert = UIAlertController.init(title: "注意", message: "これ以上選択できません!", preferredStyle: .alert) let okAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.cancel, handler: nil) alert.addAction(okAction) imagePickerController.present(alert, animated: true, completion: nil) } //cancelボタンのカスタマイズ override func imagePickerController(_ imagePickerController: DKImagePickerController, showsCancelButtonForVC vc: UIViewController) { let cancelButton = UIBarButtonItem() cancelButton.title = "戻る" cancelButton.style = .plain cancelButton.action = #selector(imagePickerController.dismiss as () -> Void) cancelButton.target = imagePickerController vc.navigationItem.leftBarButtonItem = cancelButton } @objc func selectTap() { imagePickerController.dismiss(animated: true) } }

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

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

xg63ex2b

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 でしょうね。画像はどうするのが良いのかな…。頑張ってください。
xg63ex2b

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のことを調べてみたのですが理解できるような記事がなく質問させていただきました。 何度も申し訳ありません
xg63ex2b

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)を記載してみました。 一応閉じるようにはなったのですが、これだと問題はありますでしょうか? 自分でやってみたので適切かどうかわかっていないです、、 
xg63ex2b

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が原因ではないようですね、、、
xg63ex2b

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

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

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

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

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Swift

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