Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ultravisual iOS application like animation using UICollectionViewLayout without overlapping of images

I have created the same component which currently available in UltraVisual iOS application for viewing the records in animation like parallax effects. Please find the below attached GIF image for more information. I want the same animation as in given video URL.

For that I had found the two GitHub URL which is almost same but it does not meet the same animation which used in the UltraVisual iOS application. For more information please find the below two url for the same.

URL : https://github.com/fdzsergio/SFFocusViewLayout/tree/2.0.0
URL : https://github.com/RobotsAndPencils/RPSlidingMenu

Problem :
Right now I am facing the issue of how to shrink the focused image considering the bottom part which remain static. First focused image should shrink from top (bottom part remain static) and at the same time next image will become focused considering the top of second image which remain static.

Current Code :

- (void)prepareLayout {

NSMutableArray *cache = [NSMutableArray array];

NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:0];

// last rect will be used to calculate frames past the first one.  We initialize it to a non junk 0 value
CGRect frame = CGRectZero;
CGFloat y = 0;
CGFloat footerTop = 0;

for (NSUInteger item = 0; item < numberOfItems; item++) {
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:0];
    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]
    ;
    // Important because each cell has to slide over the top of the previous one
    attributes.zIndex = item;

    // Initially set the height of the cell to the standard height
    CGFloat height = self.standardHeight;

    if (indexPath.item == self.currentFocusedItemIndex) {
        // The featured cell
        CGFloat yOffset = self.standardHeight * self.nextItemPercentageOffset;
        y = self.collectionView.contentOffset.y - yOffset;
        //y = yOffset - self.standardHeight * self.nextItemPercentageOffset;

        height = self.focusedHeight;

        //*********CURRENTLY WORKING ON THIS LINE TO ACHIEVE THE REQUIRED ANIMATION ******************
        //attributes.transform = CGAffineTransformTranslate(attributes.transform, 0, -self.collectionView.contentOffset.y+self.dragOffset); //Solution might be here…

    } else if (indexPath.item == (self.currentFocusedItemIndex + 1) && indexPath.item != numberOfItems) {

        // The cell directly below the featured cell, which grows as the user scrolls
        CGFloat maxY = y + self.standardHeight;
        height =  self.standardHeight + MAX((self.focusedHeight - self.standardHeight) * self.nextItemPercentageOffset, 0);
        y = maxY - height;
       //attributes.transform = CGAffineTransformTranslate(attributes.transform, 0, -self.collectionView.contentOffset.y+self.dragOffset); 
    } else {
        y = frame.origin.y + frame.size.height;
       //attributes.transform = CGAffineTransformTranslate(attributes.transform, 0, -self.collectionView.contentOffset.y+self.dragOffset); 
    }

    frame = CGRectMake(0, y, self.collectionView.frame.size.width, height);
    attributes.frame = frame;

    [cache addObject:attributes];
    y = CGRectGetMaxY(frame);

    if (item == numberOfItems-1) {
        footerTop = CGRectGetMaxY(frame);
    }
};

for (NSUInteger item = 0; item < numberOfItems; item++) {
    if (item == 0) {
        footerTop = footerTop + self.focusedHeight;
    } else {
        footerTop = footerTop + self.standardHeight;
    }
}

CGSize footerSize = [self footerReferenceSizeInSection:0];
if (footerSize.height > 0) {
    UICollectionViewLayoutAttributes *footerAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter withIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
    footerAttributes.zIndex = 0;
    footerAttributes.frame = CGRectMake(0, footerTop, footerSize.width, footerSize.height);
    self.footerAttributes[0] = footerAttributes;
}
self.cachedLayoutAttributes = [cache copy];
}

I had changed the existing code of (https://github.com/fdzsergio/SFFocusViewLayout/tree/2.0.0) SFFocusLayout library and here is the code on which I made changes so far. For that I had mentioned the comment in code where I feel solution lies but unable to succeed as I am struggling it from last 3 to 4 days.

Please help me and thanks in advance.

Required animation with gif file

like image 838
Gaurang Makwana Avatar asked May 28 '16 06:05

Gaurang Makwana


2 Answers

If you want to achieve animation like UltraVisual app. I modified prepareLayout Method in RPSlidingMenu.

Below are changes need to in prepareLayout Method in file RPSlidingMenuLayout.m

Need to change for first cell frame :

if (indexPath.row == topFeatureIndex) 
{
    // our top feature cell
    CGFloat yOffset = normalHeight  * topCellsInterpolation;
    yValue = self.collectionView.contentOffset.y - yOffset;
    CGFloat amountToGrow = MAX(featureHeight * topCellsInterpolation, 0);
    attributes.frame = CGRectMake(0.0f, self.collectionView.contentOffset.y -amountToGrow , screenWidth, featureHeight);
}

For Second cell but Not for last cell :

else if (indexPath.row == (topFeatureIndex + 1) && indexPath.row != numItems)
{
        yValue = lastRect.origin.y + lastRect.size.height;
        CGFloat amountToGrow = MAX((featureHeight - normalHeight) *topCellsInterpolation, 0);
        CGFloat bottomYValue = yValue + normalHeight + amountToGrow;
        NSInteger newHeight = normalHeight + amountToGrow;
        attributes.frame = CGRectMake(0.0f, 0.0f , screenWidth, screenWidth);
}

No Need to change for all other cell frames..

You can see the animation in attached gif.

Animation may look like you want !!!

Hope it will help you...

like image 83
Ketan P Avatar answered Oct 04 '22 17:10

Ketan P


Here's what I would do.

Make a UIScrollView and put your UIImage inside that. Give them all equally size except for the top one with needs to be bigger obviously. You should now be able to scroll nicely.

Now you need to write some code.

Have a reference to each UIImage.

You should get the origin.y of the top image and check for it's position as you scroll. When the position.origin.y is above UIView.frame.height you know you need to shrink it. So then shrink the image for every pixel you scroll above the view. The below image will grow for every pixel the above image is above the view.

You can implement the delegate methods from UIScrollView found in the link below. To to the position of the images as you scroll.

Be careful with how you set up you UiImages with constraints and try not to use Autolayout. It can be hard to change values set be auto layout sometimes.

UiScrollView Delegate methods

like image 36
JoakimE Avatar answered Oct 04 '22 17:10

JoakimE