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

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

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

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

Swift

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

Q&A

1回答

451閲覧

取り出した画像をScrollViewに追加したい

ROKIDOG

総合スコア20

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/08/31 15:47

取り出した画像をScrollViewに追加したいです。

取り出した複数の画像をimageView01というimageviewの配列に追加し、それをscrollviewに追加しようとしたのですが、
self.imageView01[i]!.frame = CGRect(x: x, y: y, width: width, height: height)
のところでThread 1: Fatal error: Index out of rangeというエラーが出てしまいます。。

何が問題かがわかりません。

どなたかご教授いただけませんか?

class PostViewController: UIViewController,UIScrollViewDelegate, UINavigationControllerDelegate,UIImagePickerControllerDelegate { var imageView01: [UIImageView?] = [] @IBOutlet var scrollView: UIScrollView! @IBOutlet var pageControl: UIPageControl! var resizedImage: UIImage! var selectedImages : [UIImage] = [] override func viewDidLoad() { super.viewDidLoad() } @IBAction func selectImage() { let alertController = UIAlertController(title: "画像選択", message: "シェアする画像を選択して下さい。", preferredStyle: .actionSheet) let cancelAction = UIAlertAction(title: "キャンセル", style: .cancel) { (action) in alertController.dismiss(animated: true, completion: nil) } let cameraAction = UIAlertAction(title: "カメラで撮影", style: .default) { (action) in // カメラ起動 if UIImagePickerController.isSourceTypeAvailable(.camera) == true { let picker = UIImagePickerController() picker.sourceType = .camera picker.delegate = self self.present(picker, animated: true, completion: nil) } else { print("この機種ではカメラが使用出来ません。") } } let photoLibraryAction = UIAlertAction(title: "フォトライブラリから選択", style: .default) { (action) in // アルバム起動 if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) == true { let pickerController = DKImagePickerController() pickerController.delegate = self // 選択可能上限の設定もできます pickerController.maxSelectableCount = 5 pickerController.didSelectAssets = { [unowned self] (assets: [DKAsset]) in // 選択された画像はassetsに入れて返却されますのでfetchして取り出すとよいでしょう for asset in assets { asset.fetchFullScreenImage(completeBlock: { (image, info) in // ここで取り出せます print(image,"画像") self.selectedImages.append(image!) self.imageView01 = [UIImageView(image:image)] }) } // 全体のサイズ ScrollViewフレームサイズ取得 let SVSize = self.scrollView.frame.size // 画像サイズ x 3 高さ CGSizeMake(240*3, 240) self.scrollView.contentSize = CGSize(width: SVSize.width * CGFloat(self.selectedImages.count), height: SVSize.height) //UIImageViewのサイズと位置を決めます //左右に並べる for i in 0...2 { var x:CGFloat = 0 var y:CGFloat = 0 var width:CGFloat = 240 var height:CGFloat = 240 if i == 0 { // x = 0 } else if i == 1 { x = 240 } else if i == 2 { x = 480 } // Scrollviewに追加 self.imageView01[i]!.frame = CGRect(x: x, y: y, width: width, height: height) // Scrollviewに追加 self.scrollView.addSubview(self.imageView01[i]!) //**ここでThread 1: Fatal error: Index out of rangeというエラー** } // 1ページ単位でスクロールさせる self.scrollView.isPagingEnabled = true //scroll画面の初期位置 self.scrollView.contentOffset = CGPoint(x: 0, y: 0); } self.present(pickerController, animated: true) {} } else { print("この機種ではフォトライブラリが使用出来ません。") } } alertController.addAction(cancelAction) alertController.addAction(cameraAction) alertController.addAction(photoLibraryAction) self.present(alertController, animated: true, completion: nil) }

試したこと

調べてみると、配列の要素数が空なのが要員なのかなと思いまして、

var imageView01 = [UIImageView?](repeating: 0/*初期値*/, count: selectedImages.count/*必要な要素数*/)

と書きましたがこれもうまくいきませんでした。。

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

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

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

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

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

guest

回答1

0

下記の場所では、imageView01UIImageView(image: image)を一つだけ持つ配列として確保されていますが、

Swift

1 print(image,"画像") 2 self.selectedImages.append(image!) 3 self.imageView01 = [UIImageView(image:image)]

その先では

Swift

1 for i in 0...2 { 2 // 3 self.imageView01[i]!.frame = CGRect(x: x, y: y, width: width, height: height)

という具合に、要素が3つ(0から2までなので合計3つ)の配列と決めつけて処理が行われています。

したがって、i==0 の時には大丈夫ですが、i>=1 の条件になった時には確保された要素外にアクセスするため、実行時エラーとなってしまいます。

配列に追加するのであれば、imageView01 は空の配列として確保されているため、新しい要素は append() を使って追加すれば良いのですが、必ずしも3枚追加されるとは限らないので、for 文などはそれなりに配慮した記述が必要になるのではないでしょうか。

ちなみに、
今回のご質問の範囲外になりますが、

Swift

1 asset.fetchFullScreenImage(completeBlock: { (image, info) in 2 // ここで取り出せます 3 print(image,"画像") 4 self.selectedImages.append(image!) 5 self.imageView01 = [UIImageView(image:image)] 6 })

この部分は非同期処理のため(Asset からデータを取り出す部分はネットワーク経由の処理が絡むので、リアルタイムではない)、クロージャ内部で配列に追加しても、Scroll View に追加する部分ではデータが追加されていない可能性が十分にあります。

なので、実用性を考慮すると、非同期処理に適した記述が必要になるかと思います。

投稿2020/09/01 04:33

TsukubaDepot

総合スコア5086

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問