UICollectionView は基本的にスクロールすることで小さい画面を有効に使えるようにできるUIです。マス目のセルを選択して画面遷移し、拡大表示する設定を試してみます。
Xcode 11.3.1
UICollectionView と Segue
UICollectionViewが出来上がったところから始めますので、簡単な UICollectionView を作成してください。
セルの一つを選択タップして、画面遷移にて新しい画面でその画像を拡大表示というアプリを考えて見ます。
画面遷移先の View Controller を新しく作成
Main.storyboard を選択して、上段バーにあるライブラリーからView Controller を選んで追加していきます。これを遷移先のView Controllerとします。
この View Controller に対応するClass が必要なので新らしく作成します。
メニューの「File」「New」「File…」
「iOS」-> 「Swift File」 を選択
名前を SubViewController.swift (例) としてプロジェクト内に「create」
swift ファイルはほとんど空の状態なので最低限のクラスとしての記述をしておきます。
SubViewController.swift
1 2 3 4 5 6 7 8 9 10 |
import Foundation import UIKit class SubViewController: UIViewController{ override func viewDidLoad() { super.viewDidLoad() } } |
ストーリーボードで 新しく作った View Controller を選択してライブラリーエリアの Identity Inspector に入り「Custom Class」の「Class」から、候補が選択できます
SubViewControllerを選択
これで、StoryBoard の Sub View Controller Scene とSubViewController.swift が結び付けられました。
ストーリーボードでの Segue の設定
遷移先の画面はできましたが、遷移するためにSegueというものを使います。
segueとは「あるものから次のものへ,とぎれることなく滑らかに推移する」ことを意味しています。
UICollectionView が設定されている View Controller Scene と Sub View Controller Scene を segue で結びます。
- View Controller Scene の上部バーにあるアイコンを右クリック
- manual の+をつかんでSub View Controller Sceneに持っていく
- Sub View Controller Scene から選択肢が出るので「Present Modally」を選択(Modalは非推奨になりました)
成功すれば2つのViewがつながり矢印 Segue ができます
この Segue の上にできたアイコンをクリックして、ライブラリエリアにある Attributes Inspector を選択
identifierに「toSubViewController」と記述。このキーワードは画面遷移で使われます
セルが選択されたときの挙動をコーディング
Sub View Controller Scene のView一杯に Image View を置きます
遷移先のコードを記述します。画像を表示するコードですが、
selectedImg
は遷移元から呼ばれるので合わせておく必要があります。
SubViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import UIKit class SubViewController: UIViewController{ @IBOutlet var imageView: UIImageView! var selectedImg: UIImage! override func viewDidLoad() { super.viewDidLoad() imageView.image = selectedImg // 画像のアスペクト比を維持しUIImageViewサイズに収まるように表示 imageView.contentMode = UIView.ContentMode.scaleAspectFit } } |
セルが選択されSegue を使って遷移する部分です。背景、文字色も少し変えましたがそれはストーリーボードでの変更です。
Cellが選択されSegueから次のViewContorllerへ遷移する部分のコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
... var selectedImage : UIImage ? ... // Cell が選択された場合 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { // [indexPath.row] から画像名を探し、UImage を設定 selectedImage = UIImage(named: photos[indexPath.row]) if selectedImage != nil { // SubViewController へ遷移するために Segue を呼び出す performSegue(withIdentifier: "toSubViewController",sender: nil) } } // Segue 準備 override func prepare(for segue: UIStoryboardSegue, sender: Any!) { if (segue.identifier == "toSubViewController") { let subVC: SubViewController = (segue.destination as? SubViewController)! // SubViewController のselectedImgに選択された画像を設定する subVC.selectedImg = selectedImage } } |
SubViewController を右クリックして New reference Outlet とSub View Controller Scene の imageView を結びます。
まとめると
ViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
import UIKit class ViewController: UIViewController ,UICollectionViewDataSource, UICollectionViewDelegate , UICollectionViewDelegateFlowLayout { @IBOutlet var collectionView:UICollectionView! let photos = ["nagi", "toko","saya","yumiko","yuyu", "yuka","miki","mai","kurumi","katakuriko"] var selectedImage: UIImage? override func viewDidLoad() { super.viewDidLoad() } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{ // Cell はストーリーボードで設定したセルのID let testCell:UICollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) // Tag番号を使ってImageViewのインスタンス生成 let imageView = testCell.contentView.viewWithTag(1) as! UIImageView // 画像配列の番号で指定された要素の名前の画像をUIImageとする let cellImage = UIImage(named: photos[indexPath.row]) // UIImageをUIImageViewのimageとして設定 imageView.image = cellImage // Tag番号を使ってLabelのインスタンス生成 let label = testCell.contentView.viewWithTag(2) as! UILabel label.text = photos[indexPath.row] return testCell } // Cell が選択された場合 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { // [indexPath.row] から画像名を探し、UImage を設定 selectedImage = UIImage(named: photos[indexPath.row]) if selectedImage != nil { // SubViewController へ遷移するために Segue を呼び出す performSegue(withIdentifier: "toSubViewController",sender: nil) } } // Segue 準備 override func prepare(for segue: UIStoryboardSegue, sender: Any!) { if (segue.identifier == "toSubViewController") { let subVC: SubViewController = (segue.destination as? SubViewController)! // SubViewController のselectedImgに選択された画像を設定する subVC.selectedImg = selectedImage } } // Screenサイズに応じたセルサイズを返す // UICollectionViewDelegateFlowLayoutの設定が必要 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { // 横方向のスペース調整 let horizontalSpace:CGFloat = 4 let cellSize:CGFloat = self.view.bounds.width/2 - horizontalSpace // 正方形で返すためにwidth,heightを同じにする return CGSize(width: cellSize, height: cellSize) } func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { // 要素数を入れる、要素以上の数字を入れると表示でエラーとなる return photos.count; } } |
ビルドして、iPhone X で実行、No.6のセルを選択するとアスペクト比を維持して画面いっぱいに画像が表示されます。
関連ページ:
- UICollectionView 作成
- UICollectionView セルの選択と画面遷移
Reference:
UICollectionView – UIKit | Apple Developer Documentation