🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

Q&A

解決済

1回答

1525閲覧

TableView内にCollectionViewを設置する上での疑問点

Ytan

総合スコア39

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/11/28 16:26

編集2020/11/29 02:05

現在
【Swift】TableViewとCollectionViewでよく見るUIを再現してみる]こちらを参考にして
イメージ説明
上記のような物を作りました。
大きさやLabelの追加以外のコードはリンク先の物と一緒です。

疑問点

TableViewのnumberOfRowsInSectionを4つにしているのですが
各rowのImage,Labelをそれぞれ変更したいです。

現在XibとともにCollectionViewCellを設定していて、
CollectionViewCell内で4つの関数でImage,Labelそれぞれ持たせています。

それらを例えばtableViewのindexPath.rowが0の時
CollectionViewCellの関数を呼び出して4つの条件分岐する事は可能ですか?
こちらは明らかに不可能な気がするのですが、書き方次第で出来る可能性があれば教えてもらいたいです。

それかTableViewCellの中にCollectionViewの複数のセルをそれぞれの大きさ、Image等を持たせて
各セルで条件分岐した方が良いですか?

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

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

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

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

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

guest

回答1

0

ベストアンサー

Swift

1 func setCollectionViewDataSourceDelegate 2 <D: UICollectionViewDataSource & UICollectionViewDelegate> 3 (dataSourceDelegate: D, forRow row: Int) {

というメソッドを定義してありながら、row の値を全く活用していないので、これをうまく活用すればいいのではないでしょうか。

そもそも、参考にされた記事のメソッドでは、row を渡しているにもかかわらず全く使っていないのがちょっと不思議ではあるのですが...

Swift

1class ContentsTableViewCell: UITableViewCell { 2 // 略 3 4 // 追加 5 var rowInTableViewCell: Int? 6 7 // 中略 8 9 func setCollectionViewDataSourceDelegate 10 <D: UICollectionViewDataSource & UICollectionViewDelegate> 11 (dataSourceDelegate: D, forRow row: Int) { 12 13 contentsCollectionView.delegate = dataSourceDelegate 14 contentsCollectionView.dataSource = dataSourceDelegate 15 16 // ここで row を保存しておく 17 rowInTableViewCell = row 18 19 contentsCollectionView.reloadData() 20 } 21}

という具合に、各 TableViewCell で該当する行番号(indexPath.rowの値)をセットしておき、

extension ViewController: UITableViewDelegate, UITableViewDataSource { // 略 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // SF Symbol の制限もあるので 5 に変更 return 5 } // 略 // いらないので削除する // func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { // // guard let cell = cell as? ContentsTableViewCell else { return } // cell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.section) // } // わかりやすいようにラベルに値をつける func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "ContentsTableViewCell", for: indexPath) as! ContentsTableViewCell cell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.row) // ラベルの設定 cell.titleLabel.text = "(indexPath.row) 行目のデータ" // ここで reloadData() する必要はないので削除する //cell.contentsCollectionView.reloadData() return cell } // 後略 }

といった具合で余分なメソッドを削除し、いくつかの処理を変更した上、

Swift

1extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 2 // 略 3 4 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 5 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ContentsCollectionViewCell", for: indexPath) as! ContentsCollectionViewCell 6 7 // CollectionView の親の親(は TableView になる)を得たあと、 8 // ContentsTableViewCell の rowInTableViewCell の値を得る 9 if let tableViewCell = collectionView.superview?.superview as? ContentsTableViewCell, 10 let rowInTableViewCell = tableViewCell.rowInTableViewCell { 11 12 // iOS 13 以降で使える SF Symbol の名前を作る 13 let iconName = "(rowInTableViewCell)(indexPath.row).circle" 14 15 // 該当する CollectionView に画像を表示する 16 cell.contentsImageView.image = UIImage(systemName: iconName) 17 } 18 19 return cell 20 } 21 22 // 略 23}

とすれば、CollectionViewCell が属している TableViewCell の行番号、および CollectionViewCell の row 番号に応じて任意の画像を表示することが可能です。

ただ、CollectionViewCell から TableViewCell のインスタンスを得る方法がちょっと力技なので(あらかじめ階層構造がわかっていないと使えない)、もしかしたらもう少しスマートな方法があるかもしれません。

イメージ説明

投稿2020/11/29 13:36

TsukubaDepot

総合スコア5086

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

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

Ytan

2020/11/30 09:30

setCollectionViewDataSourceDelegateの書き方やrowを渡せる事ができるのですね! superview?.superviewのような書き方もとても参考になりました。 無事rowごとに条件分岐できました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問