0

I have a UICollectionView with items. I want items in center be full color, and items closer to vertical borders of collection view to slowly fade. I came up with my custom implementation of layoutAttributesForElementsInRect but it doesn't seem to work as intended.

First, it's getting rarely called. Once at startup and sometimes later, usually when I'm near collectionView end. Second, I fail to get normalized distance, it goes from -2 to 6, and I just want 0 to 1.

What exactly am I failing here? I take the visible rect and calculate distance from cell center to its edges and then normalize it.

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray *attribs = [super layoutAttributesForElementsInRect:rect];

    CGRect visibleRect;
    visibleRect.origin = self.collectionView.contentOffset;
    visibleRect.size = self.collectionView.bounds.size;

    for (UICollectionViewLayoutAttributes *attributes in attribs) {
        if (CGRectIntersectsRect(attributes.frame, rect)) {

            CGFloat distanceFromCenter = CGRectGetMidY(visibleRect) - attributes.center.y;
            CGFloat normalizedDistance = distanceFromCenter / (visibleRect.size.height / 2);
            attributes.alpha = 1 - normalizedDistance;
        }
    }

    return attribs;
}

Update:

Here is what I want:

enter image description here

When the top line of dates (22-28) approaches the edge of collection view, I want them to slowly fade out. Same goes about the bottom row. As you can see dates 1 and 2 are already not visible since they were light grey color. Dates 1-31 are black because I highlight the month that occupies the majority of view now.

I do this via scroll view delegate method after each scroll now, but this is very ugly code.
I want to do the same in the layout attributes method.

Dvole
  • 5,725
  • 10
  • 54
  • 87

1 Answers1

3

I'm afraid I don't think you are going to have much luck with this. I think layoutAtrributesForElementsInRect is getting called so rarely because, as far as the collectionView is concerned, it's "content view" is not changing - only the contentOffset. Your scrollView delegate code should be able to recognise when the offset changes, so (presumably) you can force reload the relevant cells to give them the right alpha.

As regards your normalising code, I guess the Rect being passed to the method must be way bigger than the bounds of the collectionView - have you tried logging to establish exactly which Rect is being passed? Or maybe super is lazy and passes attributes for everything, whether they are in that Rect or not. Your CGRectIntersectsRect ought to catch that, but that too will potentially include cells whose edge falls within the Rect but whose centre falls outside. And to cope with the negative values, you should use fabs to get the absolute value of the distance from centre.

pbasdf
  • 21,386
  • 4
  • 43
  • 75