-1

I have three UICollectionView inside one UIViewController. Then I set IBOutlet for each UICollectionView

@IBOutlet weak var firstCollectionView: UICollectionView!
@IBOutlet weak var secondCollectionView: UICollectionView!
@IBOutlet weak var thirdCollectionView: UICollectionView!

and I set delegate and datasource for them. But when I want to set numberOfItemsInSection like below

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        if collectionView == firstCollectionView {
            return 1
        } else if collectionView == secondCollectionView {
            return 2
        } else if collectionView == thirdCollectionView {
            return 3
        }
    }

It keeps giving me this error Missing return in a function expected to return 'Int'

ZephyrYK
  • 31
  • 6
  • 4
    add a `return 0` at the end of the function or change the last `else if` to just `else`. You are getting this error because this function doesn't know there are 3 collectionViews. so if none of the `if` statements match then there would be no return – Scriptable May 30 '18 at 10:40
  • For better readability, I think you're better off with a switch statement here. You could put the missing `return 0` in the `default` case. – LinusGeffarth May 30 '18 at 10:45
  • 1
    It solves the problem @Scriptable – ZephyrYK May 30 '18 at 10:47
  • 1
    Possible duplicate of [Multiple collectionView in a UIViewController - IOS swift](https://stackoverflow.com/questions/28750108/multiple-collectionview-in-a-uiviewcontroller-ios-swift) – Jigar May 30 '18 at 10:49
  • It shows because you not return -> Int for required function, remove third collection view condition from else if and make it only else, error will be solve – Hardik Thakkar Jun 02 '18 at 07:28

2 Answers2

6

You need to return 0 because in numberOfItemsInSection you must have to return Int. you ended with else if but numberOfItemsInSection still need return Int value.

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if collectionView == firstCollectionView {
        return 1
    } else if collectionView == secondCollectionView {
        return 2
    } else if collectionView == thirdCollectionView {
        return 3
    } else {
        return 0
    }
}

For better readability & a little less code, I suggest you use a switch statement:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    switch collectionView {
    case firstCollectionView:
        return 1
    case secondCollectionView:
        return 2
    case thirdCollectionView:
        return 3
    default:
        return 0
    }
}
LinusGeffarth
  • 27,197
  • 29
  • 120
  • 174
3

Personally, I'd make a separate dataSource class for each collectionView, & assign them in viewDidLoad -

firstCollectionView.dataSource = FirstDataSource()
secondCollectionView.dataSource = SecondDataSource()
thirdCollectionView.dataSource = ThirdDataSource()

& either give the required data to each dataSource when it's created or make the dataSource have responsibility for getting the data as well. Putting everything into the viewController in a situation like this leads to madness...

Simple example -

class MyDataSource: UICollectionViewDataSource {

    var data: [MyData] = [] // set this when instantiating, or provide the means of creating the data which you would have put in the viewController

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.data.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell: MyCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellIdentifier", for: indexPath) as? MyCollectionViewCell else {
            return UICollectionViewCell()
        }
        // do stuff to cell
    }
}

In viewController -

self.firstCollectionView.dataSource = MyDataSource()
// etc...

Very straight forward, all it's doing is separating the code into areas of responsibility, makes it a whole lot easier to manage

SomaMan
  • 4,127
  • 1
  • 34
  • 45