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

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

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

解決済

4回答

8336閲覧

cellForItemAtのメソッドが呼ばれない原因は?

kawano108

総合スコア17

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グッド

1クリップ

投稿2018/10/22 14:48

編集2018/10/24 15:17

前提・実現したいこと

collectionViewのcellを表示させるだけのアプリを作っています。
しかし、cellForItemAtのメソッドが呼ばれず、cellを生成することができません。
もし原因がわかる方がいましたら、教えていただきたいです。
よろしくお願いします。

該当のソースコード

swift

1import UIKit 2 3class HomeController: UICollectionViewController { 4 5 override func viewDidLoad() { 6 super.viewDidLoad() 7 navigationItem.title = "Home" 8 collectionView.backgroundColor = UIColor.white 9 collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell") 10 11 } 12 13 override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 14 return 5 15 } 16 17 override func numberOfSections(in collectionView: UICollectionView) -> Int { 18 return 1 19 } 20 21 22 override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 23 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) 24 cell.backgroundColor = UIColor.orange 25 return cell 26 } 27} 28

Swift

1 2 3import UIKit 4 5@UIApplicationMain 6class AppDelegate: UIResponder, UIApplicationDelegate { 7 8 var window: UIWindow? 9 10 11 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 12 13 window = UIWindow(frame: UIScreen.main.bounds) 14 window?.makeKeyAndVisible() 15 let layout = UICollectionViewLayout() 16 window?.rootViewController = UINavigationController(rootViewController: HomeController(collectionViewLayout: layout)) 17 return true 18 } 19 20 func applicationWillResignActive(_ application: UIApplication) { 21 // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 22 // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 23 } 24 25 func applicationDidEnterBackground(_ application: UIApplication) { 26 // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 27 // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 28 } 29 30 func applicationWillEnterForeground(_ application: UIApplication) { 31 // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 32 } 33 34 func applicationDidBecomeActive(_ application: UIApplication) { 35 // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 36 } 37 38 func applicationWillTerminate(_ application: UIApplication) { 39 // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 40 } 41 42 43} 44 45

試したこと

・ブレークポイントを貼ってcellForRowAtが呼ばれているか調べた。

補足情報(FW/ツールのバージョンなど)

Swift4/Xcode10.0

// 2018/10/24 情報を追記しました!

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

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

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

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

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

guest

回答4

0

ベストアンサー

質問に掲載されているHomeControllerとAppDelegateを
そのまま実装して試してみたところ、質問通りの現象が発生するので
少し調べてみました。

すると、numberOfSectionsやnumberOfItemsInSectionは
呼ばれるのに、cellForItemAtだけ呼ばれませんでした。

ということはセルを表示するようにレイアウトできていないのだろうと思って
改めてコードを見たところ、AppDelegateで作成しているコレクションビューレイアウトが

swift

1let layout = UICollectionViewLayout()

となっていました。
初期状態のUICollectionViewLayoutを作っただけなので、
具体的なレイアウトが何も設定されておらず、セルを表示する場所がなかったということだと思います。

とりあえずこれを

swift

1let layout = UICollectionViewFlowLayout()

にしたら、表示されるようになりました。

参考にしたと言っていたYoutubeはどうしていたのだろうと思って、ざっと見たところ、7分30秒あたりのコードでは、やはりUICollectionViewFlowLayoutを使っていました。

投稿2018/10/25 01:19

TakeOne

総合スコア6299

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

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

kawano108

2018/10/25 12:40

回答ありがとうございます!! TakeOneさんのおっしゃる通り実装して見たら無事セルが表示されました! 今回のセルが表示されなかったのはcollectionViewのレイアウトを設定する記述がなかったからなんですね。 Youtubeを見返しても気づきませんでした。笑 ただ今回ハマったことでUICollectionViewLayoutを弄るにはUICollectionViewFlowLayoutが必要だと分かりました。 原因を突き止めて頂いたTakeOneさん、並びに各方面からアドバイスして頂いた皆様、ご協力ありがとうございました!
guest

0

以下はXcode 9での話でした

質問のコードではエラーが出る箇所があります。(以下の二行)

swift

1collectionView.backgroundColor = UIColor.white 2collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell") 3

ここを修正するだけでセルは表示されました。
エラーが出てないのであれば、質問に書かれていないことが原因でセルが表示されない(cellForRowAtが呼ばれない)と思われますので、情報の追記をお願いします。

投稿2018/10/24 04:16

編集2018/10/25 00:40
fuzzball

総合スコア16731

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

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

fuzzball

2018/10/24 04:21

viewDidLoad()内のcollectionViewが何者なのかが分かれば解決すると思います。
kawano108

2018/10/24 15:13

ご回答頂きありがとうございます! 僕の方ではエラーは出ていませんでした。 なので、他に原因があるかと思います。 AppDelegateを含めた情報を追記しますので、もしよろしければもう一度見ていただけないでしょうか。 よろしくお願いします。 > viewDidLoad()内のcollectionViewが何者なのかが分かれば解決すると思います。 viewDidLoad()内のcollectionViewはcollectionViewのインスタンスだと認識してます。 だからcollectionViewクラスのプロパティであるbackgroundColorやメソッドであるregisterを呼ぶことができます。ということは分かってるんですが、それが今回のようにcellForItemAtメソッドが呼ばれない理由とどう繋がるのか分かりません。 無知ですみませんが、もう少し追加の説明を頂けると幸いです。
fuzzball

2018/10/25 00:39

すみません、私のミスでした。 UICollectionViewControllerのプロパティのcollectionViewは、Xcode9までは UICollectionView? だったのに、Xcode10から UICollectionView! になってました。 なので、今のコードのままでエラーにはなりません。(ということはコードに問題は無いということです) 質問ですが、 ・viewDidLoad()は呼ばれてますか? ・「cellForItem(at:)は呼ばれているけどセルが表示されない」のではなく「cellForItem(at:)が呼ばれていない」で間違いないでしょうか?
kosanai

2018/10/25 00:52

動かない理由が特にないんですが collectionViewがOptionalじゃないのがよくわかりませんね、コンパイルエラーになると思うんですが(Swiftバージョンの違い?) 動画でも collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell") となっています collectionView?としたらどうなりますか?
fuzzball

2018/10/25 01:36 編集

>>kosanaiさん いや、! もオプショナルです。(Implicitly Unwrapped Optionalというやつ)なので ! とか ? とか付けなくても勝手にアンラップされます。Swiftというか、SDKの違いになるのかな? >>kawano108さん kosanaiさんのコメントに書かれている2018/10/25 00:23のコメントを見ました。 Storyboardは使ってないんですね。(追記されたAppDelegateのコードをちゃんと見てませんでした) さきほど付いたTakeOneさんの回答で解決しそうですね。
kosanai

2018/10/25 02:10

失礼しました、スレッド間違えました(上の方に書こうと思ってこちらに書いてしまいました) Xcode10からcollectionViewの取扱が変わっていたんですね(1つ上のコメントを読んでいませんでした)
guest

0

間違いが5,6点くらいあります
まずは簡単なチュートリアルをGoogleや参考書やQiitaなどで探して同じように組んでみてください

ちゃんと書くとこうなります

swift

1class HomeController: UIViewController { 2 3 @IBOutlet weak var homeCollectionView: UICollectionView! 4 5 override func viewDidLoad() { 6 super.viewDidLoad() 7 navigationItem.title = "Home" 8 9 homeCollectionView.delegate = self 10 homeCollectionView.datasource = self 11 12 } 13 14 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 15 return 5 16 } 17 18 func numberOfSections(in collectionView: UICollectionView) -> Int { 19 return 1 20 } 21 22 23 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 24 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) 25 cell.backgroundColor = UIColor.orange 26 return cell 27 } 28}

投稿2018/10/24 02:02

kosanai

総合スコア471

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

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

fuzzball

2018/10/24 03:56

質問のコードは UICollectionViewController を継承しています。
kosanai

2018/10/24 04:14

すいません勘違いしました わからないですねこれ。
kawano108

2018/10/24 15:23

ご回答いただきありがとうございます! 上記の例はストーリーボードを使ってUIViewControllerにCollectionViewを乗せて作った形ですね! 試しに同じように作ったら動きました! ありがとうございます! けど今回はCollectionViewControllerを使って、ソースコードのみで作りたいんです。 その理由は以下の動画を参考にしてるからです。 https://www.youtube.com/watch?v=3Xv1mJvwXok&list=PL0dzCUj1L5JGKdVUtA5xds1zcyzsz7HLj なので、回答頂いたことは大変嬉しいんですが、もし良ければCollectionViewControllerを使う場合のアドバイスを頂けると幸いです。
guest

0

cellForItemAtはUICollectionViewDataSourceプロトコルのメソッドですが、
UICollectionViewDataSource delegateが設定されていますか?
xib/StoryBoardで設定していないのであれば、コード上でHomeControllerをUICollectionViewDataSourceから派生する様にして、dataSourceに設定してあげる必要があります。

投稿2018/10/23 02:58

t_obara

総合スコア5488

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

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

fuzzball

2018/10/24 04:08

UICollectionViewControllerなので、何もしなくてもdelegateとdataSourceは繋がっています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.45%

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

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

質問する

関連した質問