NullHypothesis
NullHypothesis

Reputation: 4516

Custom UICollectionViewFlowLayout Borders

I created a Swift class that inherits from UICollectionViewFlowLayout and i've been able to successfully do some neat stuff like change the spacing between each box that it draws. I'm drawing a calendar so just imagine 28-31 boxes, 7 per row, depending on the month.

..one thing I never figured out was how to do something like make the right border blank vs. not. Or the top border. I recently changed the spacing to 0 between each box, and now the boxes' borders overlap.

I'd love to programmatically make all the right borders blank so the left border of it's next one acts as the mutual border (so it's not a double border). Then, on the last box in the collection for each row, I can make that have a right border. Know what I'm saying? Nice clean thin border around each box.

Do I do this in my override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? Perhaps somewhere else?

Thanks!

Upvotes: 3

Views: 1577

Answers (2)

NullHypothesis
NullHypothesis

Reputation: 4516

BANG! I figured it out. This is so cool, because now I can programmatically decide when to add the borders below (i.e. if x then day.layer.addSublayer(topBorder), otherwise don't add it)

func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell!
    {
        let day = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CalendarDayCollectionViewCell

        /* adds a border to entire grid */
        day.layer.borderColor = UIColor.lightGrayColor().CGColor
        //day.layer.borderWidth = 1  //can also do .cornerRadius to round out borders



        //top border
        let topBorder = CALayer()
        topBorder.frame = CGRectMake(0.0, 0.0, day.frame.size.width, 1.0);
        topBorder.backgroundColor = UIColor(white: 0.8, alpha: 1.0).CGColor


        // bottom border
        let bottomBorder = CALayer()
        bottomBorder.frame = CGRectMake(0.0, day.frame.size.height-1, day.frame.size.width, 1.0);
        bottomBorder.backgroundColor = UIColor(white: 0.8, alpha: 1.0).CGColor

        let leftBorder = CALayer()
        leftBorder.frame = CGRectMake(0.0, 0.0, 1.0, day.frame.size.height);
        leftBorder.backgroundColor = UIColor(white: 0.8, alpha: 1.0).CGColor

        let rightBorder = CALayer()
        rightBorder.frame = CGRectMake(day.frame.size.width - 1, 0.0, 1.0, day.frame.size.height);
        rightBorder.backgroundColor = UIColor(white: 0.8, alpha: 1.0).CGColor

        day.layer.addSublayer(topBorder)
        day.layer.addSublayer(bottomBorder)
        day.layer.addSublayer(leftBorder)
        day.layer.addSublayer(rightBorder)

return day
}

Upvotes: 2

zc246
zc246

Reputation: 1514

You cannot really explicitly remove one side or two sides of a border, not support by CALayer.

But based on this answer, you should be able to achieve by overlapping the cells, so you're correct that you should override func layoutAttributesForElementsInRect(rect: CGRect)

BTW, I think you can have a try with

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
    let borderWidth = 5
    return UIEdgeInsetsMake(-borderWidth,-borderWidth,-borderWidth,-borderWidth);
}

Upvotes: 0

Related Questions