5

I have an issue with a UICollectionView that doesn't want to scroll horizontally. I want to show 5 cells that I can scroll between. What is preventing my collectionview from scrolling?

import UIKit

class FeaturedCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout 
{
// Attributes
lazy var featuredVideos = UICollectionView(frame: .zero)

// Superclass initializer
required init?(coder aDecoder: NSCoder)
{
    fatalError("init(coder:) has not been implemented")
}

// Custom initializer
required override init(frame: CGRect)
{
    super.init(frame: frame)

    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .Horizontal
    featuredVideos = UICollectionView(frame: self.frame, collectionViewLayout: layout)
    featuredVideos.dataSource = self
    featuredVideos.delegate = self

    // Setting the collection view's scrolling behaviour
    featuredVideos.pagingEnabled = true
    featuredVideos.scrollEnabled = true
    featuredVideos.setContentOffset(CGPoint(x: 0,y: 0), animated: true)

    featuredVideos.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellId")

    addSubview(featuredVideos)
    setConstraints("H:|[v0(\(frame.width))]|", subviews: featuredVideos)
    setConstraints("V:|[v0(345)]", subviews: featuredVideos)
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 5
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellId", forIndexPath: indexPath)
    if indexPath.item == 1 { cell.backgroundColor = .lightGrayColor() } else { cell.backgroundColor = .brownColor() }
    return cell
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
{
    return CGSizeMake(frame.width/3, frame.height)
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat
{
    return 10
}
}

simulator view

Edit : UICollectionView actually doesn't react to any interaction, i tried "didSelectAtIndexPath", doesn't trigger.

Sn1perSkkN
  • 113
  • 1
  • 1
  • 8
  • do you have [user interaction enabled] to true? – DeyaEldeen Aug 16 '16 at 13:57
  • @DeyaEldeen it's yes by default isn't it ? Anyway, i set it to true, but the view still doesn't want to scroll. – Sn1perSkkN Aug 16 '16 at 14:09
  • please provide images or more info, anyway, let's debug ... 1- do you have an object that is created above the collection view that takes the touch instead? 2- please change the background color of the collectionView to make sure that it's frame is not still zero as initialised, 3- why the class type is UICollectionViewCell not UIViewController, 4- can you print the frame of the collection view at the end of creation logic, it's a bit difficult to track your problem. – DeyaEldeen Aug 16 '16 at 14:20
  • @DeyaEldeen Thank you for the help. I have indeed put this collection view inside a collectionviewcell (that scrolls vertically), i have added a gif image below the code (The blue view is the container of the collectionview), and the black one is the actual collection view (Which displays 2 and a half cells [in gray and brown]). – Sn1perSkkN Aug 16 '16 at 14:26
  • @DeyaEldeen Here's a better image : https://media.giphy.com/media/ozr5mytX26H6g/giphy.gif – Sn1perSkkN Aug 16 '16 at 14:34
  • https://stackoverflow.com/questions/31681481/ios9-uitableviewcellcontentview-is-covering-up-controls-inside-cell – OhadM May 24 '21 at 17:29

3 Answers3

1

To realize UICollectionView with UICollectionView in UICollectionViewCell try this idea (both of the collectionViews are scrollable):

CollectionViewController.swift

import UIKit

class CollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
{
var featuredVideos: UICollectionView?

override func viewDidLoad() {

    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .Horizontal
    featuredVideos = UICollectionView(frame: UIScreen.mainScreen().bounds, collectionViewLayout: layout)

    featuredVideos!.dataSource = self
    featuredVideos!.delegate = self

    // Setting the collection view's scrolling behaviour
    featuredVideos!.pagingEnabled = true
    featuredVideos!.scrollEnabled = true
    featuredVideos!.setContentOffset(CGPoint(x: 0,y: 0), animated: true)

    featuredVideos!.registerClass(CollectionViewCell.self, forCellWithReuseIdentifier: "cellId")
    view.addSubview(featuredVideos!)

}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 5
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellId", forIndexPath: indexPath) as! CollectionViewCell
    cell.initCell()
    if indexPath.item%2 == 0
    {
        cell.backgroundColor = .lightGrayColor()
    }
    else
    {
        cell.backgroundColor = .brownColor()
    }
    return cell
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
{
    return CGSizeMake(300, UIScreen.mainScreen().bounds.height)
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat
{
    return 10
}
}

CollectionViewCell.swift

class CollectionViewCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate
{
var collectionView: UICollectionView?

func initCell () {
    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .Horizontal
    var collectionViewBounds = self.bounds
    collectionViewBounds.size.height -= 80
    collectionViewBounds.origin.y = 40
    collectionView = UICollectionView(frame: collectionViewBounds, collectionViewLayout: layout)

    collectionView!.dataSource = self
    collectionView!.delegate = self

    // Setting the collection view's scrolling behaviour
    collectionView!.pagingEnabled = true
    collectionView!.scrollEnabled = true
    collectionView!.setContentOffset(CGPoint(x: 0,y: 0), animated: true)

    collectionView!.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellWithCollectionView")
    addSubview(collectionView!)

}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellWithCollectionView", forIndexPath: indexPath)
    if indexPath.item%2 == 0
    {
        cell.backgroundColor = .blueColor()
    }
    else
    {
        cell.backgroundColor = .whiteColor()
    }
    return cell
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
{
    return CGSizeMake(100, collectionView.frame.height)
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat
{
    return 10
}

}
Vasily Bodnarchuk
  • 24,482
  • 9
  • 132
  • 127
  • 1
    please comment with what you have changed and why, thanks. – DeyaEldeen Aug 16 '16 at 14:44
  • Sorry, but I can't understand. Should I comment where was Sn1perSkkN errors in code? Or, why I edit my answer? – Vasily Bodnarchuk Aug 16 '16 at 14:48
  • @VasilyBodnarchuk The actual class "featuredCell" is a UICollectionViewCell and i want to add a UICollectionView inside it "featuredVideos". So I first created a new class and used your code, I inherited from the UICollectionViewCell in order to make it work, but it didnt. I then, replaced my code (initializing featuredVideos...) but it still doesn't solve the problem. The "featuredVideos" refuses to scroll :( – Sn1perSkkN Aug 16 '16 at 15:06
  • You want to set UICollectionView in UICollectionViewCell? – Vasily Bodnarchuk Aug 16 '16 at 15:23
  • The UICollectionViewCell will contain the (UICollectionView + Another View) – Sn1perSkkN Aug 16 '16 at 15:28
1

I've found the problem.

In the parent view, I added a border to this view (which is a UICollectionViewCell in the parent view) inside the cellForItemAtIndexPath(), and that caused the view to only load the first cells and refuse any interaction.

I fixed it by adding the border in the init() inside the "child view" which worked just fine.

Thank you all for your help :)

Sn1perSkkN
  • 113
  • 1
  • 1
  • 8
  • I had a similar problem and this lead me to the solution: I had a fixed size Collection View and then added other element which moved the collection view (and part of this was out of the screen), so when I was adding cells the scroll did not work because the number of elements was yet inside the space in which the scrolling should not be needed. I solved it modifying the visual constraints. – javi_swift Jun 21 '18 at 09:22
0

If you are using Scroll View delegate methods, then this problem may come.

So, resolve by adding this line into those delegate methods :

func scrollViewDidScroll(_ scrollView: UIScrollView) {        
    if scrollView.isKind(of: UICollectionView.self) 
      {
         return
      };
}
coDe murDerer
  • 1,858
  • 4
  • 20
  • 28