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

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

新規登録して質問してみよう
ただいま回答率
85.50%
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

0回答

1457閲覧

collectionViewのセルサイズが、再生成するまで正しく表示されない。

Y_M

総合スコア265

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クリップ

投稿2019/05/10 04:13

編集2022/01/12 10:55

前提・実現したいこと

ViewControllerTableViewを配置し、
TableViewCell上にCollectionViewを配置しています。

画面の横幅を基準とし、5等分にしたものをCollectionViewCellの横幅とし、
隙間なく配置する画面を想定しています。

しかし処理の完成後に実行すると、表示直後はうまく表示されず、
TableViewをスクロールし、TableViewCellが再生成されると、正しいサイズで表示されます。

こちらを表示直後から正しい形で表示したいのですが、実装方法が思いつきませんでした。

該当のソースコード

Swift

1import UIKit 2 3class ViewController: UIViewController { 4 5 @IBOutlet weak var sampleTableView: UITableView! 6 7 override func viewDidLoad() { 8 super.viewDidLoad() 9 10 self.sampleTableView.delegate = self 11 self.sampleTableView.dataSource = self 12 13 let nib = UINib(nibName: "SampleTableViewCell", bundle: nil) 14 self.sampleTableView.register(nib, forCellReuseIdentifier: "Cell") 15 } 16 17 override func viewWillAppear(_ animated: Bool) { 18 super.viewWillAppear(animated) 19 20 self.sampleTableView.reloadData() // 追加 21 } 22 23} 24 25extension ViewController: UITableViewDelegate, UITableViewDataSource { 26 27 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 28 return 5 29 } 30 31 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 32 return UIScreen.main.bounds.width / 5.0 * 6.0 33 } 34 35 func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 36 guard let cell = cell as? SampleTableViewCell else { return } 37 cell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.row) 38 } 39 40 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 41 let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SampleTableViewCell 42 return cell 43 } 44 45} 46 47extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource { 48 49 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 50 return 30 51 } 52 53 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 54 print(indexPath.row) 55 } 56 57 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 58 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! SampleCollectionViewCell 59 print(cell.frame.size) 60 return cell 61 } 62 63}

Swift

1import UIKit 2 3class SampleTableViewCell: UITableViewCell { 4 5 @IBOutlet weak var sampleCollectionView: UICollectionView! 6 7 override func awakeFromNib() { 8 super.awakeFromNib() 9 10 let nib = UINib(nibName: "SampleCollectionViewCell", bundle: nil) 11 self.sampleCollectionView.register(nib, forCellWithReuseIdentifier: "Cell") 12 } 13 14 func setCollectionViewDataSourceDelegate<D: UICollectionViewDataSource & UICollectionViewDelegate>(dataSourceDelegate: D, forRow row: Int) { 15 let layout = UICollectionViewFlowLayout() 16 layout.minimumLineSpacing = 0.0 17 layout.minimumInteritemSpacing = 0.0 18 layout.itemSize = CGSize(width: self.sampleCollectionView.frame.width / 5, height: self.sampleCollectionView.frame.width / 5) 19 20 print(self.sampleCollectionView.frame) // 追加 21 22 self.sampleCollectionView.delegate = dataSourceDelegate 23 self.sampleCollectionView.dataSource = dataSourceDelegate 24 self.sampleCollectionView.collectionViewLayout = layout 25 self.sampleCollectionView.reloadData() 26 } 27 28}

Swift

1 2import UIKit 3 4class SampleCollectionViewCell: UICollectionViewCell { 5 6 override func awakeFromNib() { 7 super.awakeFromNib() 8 // Initialization code 9 } 10 11}

実際の画面

イメージ説明

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

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

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

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

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

fuzzball

2019/05/10 04:30

viewWillAppearでリロードしたらどうなります?
Y_M

2019/05/10 04:42

リロード先はTableViewですかね。 コードに追記、実行しましたが変わらずでした。
fuzzball

2019/05/10 04:49

setCollectionViewDataSourceDelegate(dataSourceDelegate:forRow:) の中にprint(self.sampleCollectionView.frame) を追加して、おかしい時と正しいときの値を教えて下さい。
Y_M

2019/05/10 04:52

おかしい時:(0.0, 0.0, 320.0, 319.5) 正しい時:(0.0, 0.0, 375.0, 449.6666666666667)
fuzzball

2019/05/10 05:28

やはりViewのサイズが確定する前に計算しちゃってるので、確定後に計算するようにしないとダメですね。 いろいろと何も考えずに、とりあえず正しく表示するなら、willDisplayじゃなくてcellForRowAtでサイズ計算を呼び出す(&viewWillAppearでリロード必要かも)ようにすればいけそうな気はしますが。
Y_M

2019/05/10 05:40 編集

cellForRowAtで計算を呼び出せば行けそうですね。 ただ再利用されるたびに呼び出されると思うので、重くなりそうです。 ライフサイクル的な問題だと思うのですが、 viewDidAppearにリロード処理を入れると、 画面がちらついちゃいますが、きちんと表示できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問