3

Note it turned out it was a simple mistake the cells would not "sit on the bottom". However, it's an interesting question: "how to move the cells up and down." Below a brute force solution: writing your own flow layout.

I was amazed that the only way to do it is entirely subclass UICollectionViewFlowLayout and write some tricky code in layoutAttributesForElementsInRect.

It's possible this will help someone in the future, as there is very little example code for layoutAttributesForElementsInRect around. Hope it helps.

--

It turns out the reason my cells would not sit on the bottom was that I previously had this in my UICollectionViewController...

-(void)viewDidLoad
{
[super viewDidLoad];
// the following code is very useful to, for example,
// "nudge short lists towards the middle..." - if you want the list
// to more sit in the middle of the screen, when only a few items.
cvHeight = CGRectGetHeight(self.collectionView.bounds);
[self.collectionView setContentInset:
       UIEdgeInsetsMake(cvHeight * 0.175, 0, cvHeight * 0.30, 0) ]; //top,l,b,r
}

of course, when I changed to a "full-view cell size" (one cell per screen), that code fails.


I have a simple UICollection view which is the width of an iPhone and about 250 high. The cells are the exact same size as the collection view.

The cells will not center, they always sit high. (i.e., outside the view.)

enter image description here

My collection view "sizes" in storyboard are all just zero. What could be the problem?

Fattie
  • 27,874
  • 70
  • 431
  • 719

2 Answers2

4

Here's one "brute force" way to solve the problem -- write your own FlowLayout!!

It works ...

class SimpleFlowLayout: UICollectionViewFlowLayout {


override init() {
    super.init()

    initialize()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    initialize()
}

func initialize() {
    self.scrollDirection = .horizontal
    self.minimumInteritemSpacing = 0.0
    self.minimumLineSpacing = 0.0

}

override var collectionViewContentSize: CGSize {

    return super.collectionViewContentSize
}

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {


    let allItems = super.layoutAttributesForElements(in: rect)
    for  attribute in allItems! {
        print ("attribute.frame.origin.y  .....  \(attribute.frame.origin.y)")
        attribute.frame = CGRect(x: attribute.frame.origin.x,
                                 y: attribute.frame.origin.y + 34,
                             width: attribute.frame.size.width,
                            height: attribute.frame.size.height)

            // "go figure" ... add 34
    }

    return allItems;

}

The way you "set" a UICollectionViewFlowLayout is basically like this...

class YourFancyDisplay: UICollectionViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView!.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
        collectionView!.collectionViewLayout = SimpleFlowLayout()
        ...
Fattie
  • 27,874
  • 70
  • 431
  • 719
  • I just ticked this since it may help someone w/ example code for flow layout. It's pretty much the only way to move them up and down! – Fattie Jul 28 '14 at 16:45
  • @Fattie how exactly are you implementing SimpleLayout? Where are you using it as a subclass – Stefan Jun 04 '17 at 06:38
  • I understand the implementation. However, I have one final question. In override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? it looks like you are set the attributes for every cell in every index path. What if you cell two to have a different layout different than item one. – Stefan Jun 04 '17 at 20:41
  • het Stef, just as in table view, you simply decide which custom cell to use. see any tutorial for that - cheers, good luck – Fattie Jun 04 '17 at 20:48
  • I looked at layoutAttributesForElements in the documentation and it states that it: Returns the layout attributes for all of the cells and views in the specified rectangle. Meaning custom cells would still conform to the layout.. Is there any other form/version of the function? – Stefan Jun 04 '17 at 22:55
1

Try this. hopefully, it can help

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return collectionView.frame.size;
}

(For future readers, indeed you also typically need the other one ...)

-(CGSize) collectionView:(UICollectionView *)collectionView
     layout:(UICollectionViewLayout *)collectionViewLayout
     sizeForItemAtIndexPath:(NSIndexPath *)indexPath
    {
    return self.view.frame.size;
    }

-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView
   layout:(UICollectionViewLayout*)collectionViewLayout
   insetForSectionAtIndex:(NSInteger)section
    {
    return UIEdgeInsetsMake(0,0,0,0);   //t,l,b,r
    }
NiñoScript
  • 4,523
  • 2
  • 27
  • 33