How to get 1 pixel width borders in UICollectionView cells? (code provided)
There are a few strategies you can take to solve this issue. Which is best depends on some of the details of your layout.
Option 1: Half Borders
Draw borders of 1/2 the desired width around each item. This has been suggested. It achieves the correct width for borders between items, but the borders around the edge of the collection will also be half the desired width. To solve this you can draw a border around the entire collection, or sections.
If you're month layout only renders days in a given month, meaning each month has a unique non-rectangular shape, fixing the edge borders is more complicated than it's worth.
Option 2: Overlapping Cells
Draw the full border around each item but adjust the frames so they overlap by half of the width of the borders, hiding the redundancy.
This is the simplest strategy and works well, but be aware of a few things:
- Be mindful that the outer edges of the layout are also slightly changed. Compensate for this if necessary.
- The borders will overlap, so you can't use semi-transparent borders.
- If not all the borders are the same color, some edges will be missing. If there is just a single cell with a different border, you can adjust the item's z-index to bring it on top of the other cells.
Option 3: Manual Drawing
Rather than using borders on the cell at all, you can add a border around the container and then manually draw the borders in the superview. This could be accomplished by overriding drawRect(_:)
and using UIBezierPaths
to draw horizontal and vertical lines at the intervals of the cells. This is the most manual option. It gives you more control, but is much more work.
Option 4: Draw Only Some Borders in Each Cell
Rather than assigning the layer's border width and border color, which draws a border around the entire view, selectively draw edges of cells. For example: each cell could only draw it's bottom and right edge, unless there is no cell above or to the right of it.
This can again lead to complications if you have an irregular grid. It also requires each cell to know about it's context in the grid which requires more structure. If you go this route, I would suggest subclassing UICollectionViewLayoutAttributes
and adding additional information about which edges should be drawn. The edge drawing itself can again be done by creating UIBezierPath
's in drawRect(_:)
for each edge.
I usually divide the border width by the screen scale:
width = 1.0f / [UIScreen mainScreen].scale