Ultravisual iOS 应用程序,如使用 UICollectionViewLayout 的动画而不重叠图像

Ultravisual iOS application like animation using UICollectionViewLayout without overlapping of images

我创建了当前在 UltraVisual iOS 应用程序中可用的相同组件,用于查看动画中的记录,如 parallax 效果。请找到下面附加的 GIF 图像以获取更多信息。我想要与给定视频 URL.

中相同的动画

为此,我找到了两个 GitHub URL,它们几乎相同,但不符合 UltraVisual iOS 应用程序中使用的相同动画。有关更多信息,请查找以下两个 url 相同的内容。

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

问题:
现在我面临着如何缩小聚焦图像的问题,考虑到底部保持静止。第一张对焦图像应该从顶部缩小(底部保持静止),同时考虑到第二张图像的顶部保持静止,下一张图像将变得对焦。

当前代码:

- (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];
}

我已经更改了 (https://github.com/fdzsergio/SFFocusViewLayout/tree/2.0.0) SFFocusLayout 库的现有代码,这里是我到目前为止所做更改的代码。为此,我在代码中提到了 comment ,我觉得解决方案就在那里,但由于我在过去 3 到 4 天里一直在努力解决,所以无法成功。

请帮助我并提前致谢。

这是我会做的。

制作一个 UIScrollView 并将您的 UIImage 放入其中。给它们同样的大小,除了最上面的那个显然需要更大一些。您现在应该可以很好地滚动了。

现在您需要编写一些代码。

引用每个 UIImage。

您应该获取顶部图像的 origin.y 并在滚动时检查它的位置。当 position.origin.y 高于 UIView.frame.height 时,你知道你需要缩小它。因此,然后缩小您在视图上方滚动的每个像素的图像。下图将随着上图在视图上方的每个像素而增长。

您可以从下面 link 中找到的 UIScrollView 实现委托方法。滚动到图像的位置。

注意如何设置带有约束的 UiImage,尽量不要使用自动布局。有时很难更改设置为自动布局的值。

UiScrollView Delegate methods

如果你想实现类似UltraVisual的动画应用。我在 RPSlidingMenu.

中修改了 prepareLayout 方法

下面是 prepareLayout 文件 RPSlidingMenuLayout.m

中的方法需要进行的更改

需要更改第一个单元格框架:

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);
}

对于第二个单元格但不是最后一个单元格:

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);
}

无需更改所有其他单元格框架..

您可以在附加的 gif 中看到动画。

希望对你有所帮助...