4

I have 2 collection views on the same screen, and I have the data source and delegate implemented for both in the same view controller. However, the delegate methods such as didSelectItemAtIndexPath is only called for one.

Other info:

  • Both collection views have a cell with an image.
  • AllowSelection and UserInteractionEnabled is set to true in both collection views
  • User interaction enabled on the images
  • Delegate and data source are set on the storyboard from both collection views to the view controller
  • Collection views are displayed properly

Both collection views have the same setup, yet only one delegate works. Would you have any clues what could be setting this up?

The collection views are inside a view that has a scroll view. Could this be somehow related?

EDIT 2:

Project with the same problem: https://github.com/iagomr/ProblemWithAutoLayout

EDIT 1:

Somehow this has to do with autolayout constraints, because if I pin the bottom collection view to the bottom of the screen instead of the bottom of other collection view, it starts working.

This is all due to the fact that I need to build a tall screen, and added everything into a view inside a scroll view 1000 points tall.

Code:

//MARK: - CollectionView Delegate
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {

    println("Called")
}

//MARK: - CollectionView DataSource
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if collectionView == thisCV {
        return 1

    } else if collectionView == thisOtherCV{
        return 1
    }
}

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 1
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    if collectionView == "thisCV" {
        if let thisCell = collectionView.dequeueReusableCellWithReuseIdentifier("thisCell", forIndexPath: indexPath) as? thisCollectionViewCell {

            thisCell.image = image

            return thisCell
        }

    } else if collectionView == "thisOtherCV"{
        if let thisOtherCell = collectionView.dequeueReusableCellWithReuseIdentifier("thisOtherCell", forIndexPath: indexPath) as? OtherCollectionViewCell {

            thisOtherCell.image = image

            return thisOtherCell
        }
    }

    return UICollectionViewCell()
}
iagomr
  • 442
  • 4
  • 13
  • are both the collectionViews have userInteraction Enabled? – sateesh Aug 10 '15 at 12:18
  • Yes sateesh, they have – iagomr Aug 10 '15 at 12:20
  • Did you set the delegate property for both of the collection views ? – Quentin Hayot Aug 10 '15 at 12:21
  • yes, both have delegate and data source set to self in the view controller – iagomr Aug 10 '15 at 12:24
  • Try setting the delegate and data source using code. For example in viewDidLoad. Maybe storyboard nullifies one of the connections because it thinks they are "the same"? – Andriy Gordiychuk Aug 10 '15 at 13:17
  • @AndriyGordiychuk, I have changed to that. I have also separated Data Source to another file and see if it would do anything, but no luck. – iagomr Aug 10 '15 at 14:01
  • @iagomr ok. Then check if it can be a problem with your cells. To do it, create the same cells for both collection views (using the cells from the collection view which calls didSelectItem correctly) – Andriy Gordiychuk Aug 10 '15 at 14:06
  • I have tried without success. The collection views are inside a view that has a scroll view. Could this be somehow related? – iagomr Aug 10 '15 at 14:42
  • 1
    I doubt that comparing an instance of `UICollectionView` with a literal string works e.g. collectionView == "thisCV"`` – vadian Aug 10 '15 at 14:46
  • @iagomr when you say "without success" do you mean that both collection views now display the same cells and only one collection view calls didSelectItem? Also check the comment by vadian - he is right about comparing instance of UICollectionView to a literal – Andriy Gordiychuk Aug 10 '15 at 14:56
  • @AndriyGordiychuk yes, that's what I mean by success. I'm not using that, I was just trying to make it clear. Even without it, the didSelectItemAtIndexPath is simply not called when I tap a cell from one of the collection views – iagomr Aug 10 '15 at 17:27
  • Somehow this has to do with autolayout constraints, because if I remove constraints it starts working.. – iagomr Aug 10 '15 at 18:09
  • disabling User interaction enabled on the images?? – HMHero Aug 10 '15 at 19:00
  • @iagomr if removing constraints helps it means that the images which you see are drawn outside of contentView of your cells. If this is the case there is nothing strange in the fact that didSelectItem is not called. Can you upload a zip of your project (or relevant files)? – Andriy Gordiychuk Aug 10 '15 at 20:15
  • @AndriyGordiychuk, here it is: https://github.com/iagomr/ProblemWithAutoLayout – iagomr Aug 11 '15 at 08:17
  • The project in this repository works perfectly fine for me. I even changed the implementation of `didSelectItemAtIndexPath` to print different messages for the two collection views and there doesn't seem to be a problem. – halileohalilei Aug 11 '15 at 08:51
  • @halileohalilei you did not change anything? If I tap the bottom cell, it doesn't print anything on the console for me. – iagomr Aug 11 '15 at 09:05
  • @iagomr hmm ok I got it now. The problem only seems to occur if the second collection view is located outside the boundaries of the initial position of the containing view. I have no idea why this would occur though. – halileohalilei Aug 11 '15 at 10:39

1 Answers1

3

I can confirm that didSelectItem is not getting called. If constant for top-bottom constraint between two collection views is changed from 501 to 0 it is working.

This problem is most likely related to the fact that you have two scroll views (collection views) inside of another scroll view. Overall, I would say, that you should modify your UI. I would suggest two ways of fixing it

Using single collection view

Use just one collection view with different sections for different content. Also, do NOT embed it in the scroll view - collection view already has a scroll view so you should be able to scroll easily. You can also dequeue different class of cells for different sections so you should be able to do everything which you want to do now.

If you want a starting point, here is a good tutorial which should help you with that.

Using scroll view

If you want to setup your UI in Interface Builder remove both collection views and simply add all of your UI inside of scroll view. Place UIButton in places where you want clicking to produce action.

You can even assign the same action to each button and then differentiate which one was triggered by assigning custom tags to each of them.

Community
  • 1
  • 1
Andriy Gordiychuk
  • 6,163
  • 1
  • 24
  • 59